💾 Archived View for perso.pw › blog › rss.xml captured on 2024-08-18 at 18:13:09.
⬅️ Previous capture (2024-07-09)
-=-=-=-=-=-=-
<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <title>Solene'%</title> <description></description> <link>gemini://perso.pw/blog/</link> <atom:link href="gemini://perso.pw/blog/rss.xml" rel="self" type="application/rss+xml" /> <item> <title>Using Firefox remote debugging feature</title> <description> <![CDATA[ <pre># Introduction Firefox has an interesting features for developers, its ability to connect a Firefox developers tools to a remote Firefox instance. This can really interesting in the case of a remote kiosk display for instance. The remote debugging does not provide a display of the remote, but it gives you access to the developer tools for tabs opened on the remote. # Setup The remote firefox you want to connect to must be started using the command line parameter `--start-debugger-server`. This will make it listen on the TCP port 6000 on 127.0.0.1. Be careful, there is another option named `remote-debugging-port` which is not what you want here, but the names can be confusing (trust me, I wasted too much time because of this). Before starting Firefox, a few knobs must be modified in its configuration. Either search for the options in `about:config` or create a `user.js` file in the Firefox profile directory with the following content:
user_pref("devtools.chrome.enabled", true);
user_pref("devtools.debugger.remote-enabled", true);
user_pref("devtools.debugger.prompt-connection", false);
This enables the remote management and removes a prompt upon each connection, while this is a good safety measure, it is not practical for remote debugging. When you start Firefox, the URL input bar should have a red background. # Remote connection Now, you need to make a SSH tunnel to that remote host where Firefox is running in order to connect to the port. Depending on your use case, a local NAT could be done to expose the port to a network interface or VPN interface, but pay attention to security as this would allow anyone on the network to control the Firefox instance. The SSH tunnel is quite standard: `ssh -L 6001:127.0.0.1:6000`, the remote port 6000 is exposed locally as 6001, this is important because your own Firefox may be using the port 6000 for some reasons. In your own local Firefox instance, visit the page `about:debugging`, add the remote instance `localhost:6001` and then click on Connect on its name on the left panel. Congratulations, you have access to the remote instance for debugging or profiling websites. => static/firefox-debug-add-remote-fs8.png Input the remote address localhost:6001 and click on Add => static/firefox-debug-left-panel-fs8.png Click on connect on the left => static/firefox-debug-access-fs8.png Enjoy your remote debugging session # Conclusion While it can be tricky to debug a system you can directly see, especially if it is a kiosk in production that you can see / use in case of a problem. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/remote-firefox-debug.gmi</guid> <link>gemini://perso.pw/blog//articles/remote-firefox-debug.gmi</link> <pubDate>Thu, 08 Aug 2024 00:00:00 GMT</pubDate> </item> <item> <title>Full-featured email server running OpenBSD</title> <description> <![CDATA[ <pre># Introduction This blog post is a guide explaining how to setup a full-featured email server on OpenBSD 7.5. It was commissioned by a customer of my consultancy who wanted it to be published on my blog. Setting up a modern email stack that does not appear as a spam platform to the world can be a daunting task, the guide will cover what you need for a secure, functional and low maintenance email system. The features list can be found below:
set block-policy drop
set loginterface egress
set skip on lo0
match in all scrub (no-df random-id max-mss 1440)
antispoof quick for { egress }
tcp_ports = "{ smtps smtp submission imaps pop3s sieve ssh http }"
block all
pass out inet
pass out inet6
pass in proto icmp
pass in on egress inet6 proto icmp6 all icmp6-type { routeradv neighbrsol neighbradv }
pass in on egress inet6 proto udp from fe80::/10 port dhcpv6-server to fe80::/10 port dhcpv6-client no state
pass in on egress proto tcp from any to any port $tcp_ports
block return in on ! lo0 proto tcp to port 6000:6010
block return out log proto {tcp udp} user _pbuild
# DNS If you want to run your own email server, you need a domain name configured with a couple of DNS records about the email server. ## MX records => https://en.wikipedia.org/wiki/MX_record Wikipedia page: MX record The MX records list the servers that should be used by outside SMTP servers to send us emails, this is the public list of our servers accepting emails for a given domain. They have a weight associated to each of them, the server with the lowest weight should be used first and if it does not respond, the next server used will be the one with a slightly higher weight. This is a simple mechanism that allow setting up a hierarchy. I highly recommend setting up at least two servers, so if your main server fails is unreachable (host outage, hardware failure, upgrade ongoing) the emails will be sent to the backup server. Dovecot bundles a program to synchronize mailboxes between servers, one way or two-way, one shot or continuously. If you have no MX records in your domain name, it is not possible to send you emails. It is like asking someone to send you a post card without giving them any clue about your real address. Your server hostname can be different from the domain apex (raw domain name without a subdomain), a simple example would be to use `mail.domain.example` for the server name, this will not prevent it from receiving/sending emails using `@domain.example` in email addresses. In my example, the domain puffy.cafe mail server will be mail.puffy.cafe, giving this MX record in my DNS zone:
IN MX 10 mail.puffy.cafe.
## SPF => https://en.wikipedia.org/wiki/Sender_Policy_Framework Wikipedia page: SPF record The SPF record is certainly the most important piece of the email puzzle to detect spam. With the SPF, the domain name owner can define which servers are allowed to send emails from that domain. A properly configured spam filter will give a high spam score to incoming emails that are not in the sender domain SPF. To ease the configuration, that record can automatically include all MX defined for a domain, but also A/AAAA records, so if you only use your MX servers for sending, a simple configuration allowing MX servers to send is enough. In my example, only mail.puffy.cafe should be legitimate for sending emails, any future MX server should also be allowed to send emails, so we configure the SPF to allow all MX defined servers to be senders.
600 IN TXT "v=spf1 mx -all"
## DKIM => https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail Wikipedia page: DKIM signature When used, the DKIM is a system allowing a receiver to authenticate a sender, based on an asymmetric cryptographic keys. The sender publishes its public key on a TXT DNS record before signing all outgoing emails using the private key. By doing so, receivers can validate the email integrity and make sure it was sent from a server of the domain claimed in the From header. DKIM is mandatory to not be classified as a spamming server. The following set of commands will create a 2048 bits RSA key in `/etc/mail/dkim/private/puffy.cafe.key` with its public key in `/etc/mail/dkim/puffy.cafe.pub`, the `umask 077` command will make sure any file created during the process will only be readable by root. Finally, you need to make the private key readable to the group `_rspamd`. Note: the umask command will persist in your shell session, if you do not want to create files/directory only readable by root after this, either spawn a new shell, or run the set of commands in a new shell and then exit from it once you are done.
umask 077
mkdir /etc/mail/dkim/private/
openssl genrsa -out /etc/mail/dkim/private/puffy.cafe.key 2048
openssl rsa -in /etc/mail/dkim/private/puffy.cafe.key -pubout -out /etc/mail/dkim/puffy.cafe.pub
chgrp _rspamd /etc/mail/dkim/private/puffy.cafe.key /etc/mail/dkim/private/
chmod 440 /etc/mail/dkim/private/puffy.cafe.key
chmod 775 /etc/mail/dkim/private/
In this example, we will name the DKIM selector `dkim` to keep it simple. The selector is the name of the key, this allows having multiple DKIM keys for a single domain. Add the DNS record like the following, the value in `p` is the public key in the file `/etc/mail/dkim/puffy.cafe.pub`, you can get it as a single line with the command `awk '/PUBLIC/ { $0="" } { printf ("%s",$0) } END { print }' /etc/mail/dkim/puffy.cafe.pub`: Your registrar may offer to add the entry using a DKIM specific form. There is nothing wrong doing so, just make sure the produced entry looks like the entry below.
dkim._domainkey IN TXT "v=DKIM1;k=rsa;p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3tIFelMk74wm+cJe20qAUVejD0/X+IdU+A2GhAnLDpgiA5zMGiPfYfmawlLy07tJdLfMLObl8aZDt5Ij4ojGN5SE1SsbGC2MTQGq9L2sLw2DXq+D8YKfFAe0KdYGczd9IAQ9mkYooRfhF8yMc2sMoM75bLxGjRM1Fs1OZLmyPYzy83UhFYq4gqzwaXuTvxvOKKyOwpWzrXzP6oVM7vTFCdbr8E0nWPXWKPJhcd10CF33ydtVVwDFp9nDdgek3yY+UYRuo/iJvdcn2adFoDxlE6eXmhGnyG4+nWLNZrxIgokhom5t5E84O2N31YJLmqdTF+nH5hTON7//5Kf/l/ubwIDAQAB"
## DMARC => https://en.wikipedia.org/wiki/DMARC Wikipedia page: DMARC record The DMARC record is an extra mechanism that comes on top of SPF/DKIM, while it does not do much by itself, it is important to configure it. DMARC could be seen as a public notice explaining to servers receiving emails whose sender looks like your domain name (legit or not) what they should do if SPF/DKIM does not validate. As of 2024, DMARC offers three actions for receivers:
_dmarc IN TXT "v=DMARC1;p=reject;rua=mailto:dmarc@puffy.cafe;sp=reject;aspf=r;"
## PTR (Reverse DNS) => https://en.wikipedia.org/wiki/Reverse_DNS_lookup Wikipedia page: PTR record An older mechanism used to prevent spam was to block, or consider as spam, any SMTP server whose advertised hostname did not match the result of the reverse lookup of its IP. Let's say "mail.foobar.example" (IP: A.B.C.D) is sending an email to my server, if the result of the DNS request to resolve the PTR of A.B.C.D is not "mail.foobar.example", the email would be considered as spam or rejected. While this is superseded by SPF/DKIM and annoying as it is not always possible to define a PTR for a public IP, the reverse DNS setup is still a strong requirement to not be considered as a spamming platform. Make sure the PTR matches the system hostname and not the domain name itself, in the example above the PTR should be `mail.foobar.example` and not `foobar.example`. # System configuration ## Acme-client The first step is to obtain a valid TLS certificate, this requires configuring acme-client, httpd and start httpd daemon. Copy the acme-client example `cp /etc/examples/acme-client.conf /etc/` Modify `/etc/acme-client.conf` and edit only the last entry to configure your own domain, mine looks like this:
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
authority letsencrypt-staging {
api url "https://acme-staging-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem"
}
authority buypass {
api url "https://api.buypass.com/acme/directory"
account key "/etc/acme/buypass-privkey.pem"
contact "mailto:me@example.com"
}
authority buypass-test {
api url "https://api.test4.buypass.no/acme/directory"
account key "/etc/acme/buypass-test-privkey.pem"
contact "mailto:me@example.com"
}
domain mail.puffy.cafe {
# you can remove the line "alternative names" if you do not need extra subdomains
# associated to this certificate
# imap.puffy.cafe is purely an example, I do not need it
alternative names { imap.puffy.cafe pop.puffy.cafe }
domain key "/etc/ssl/private/mail.puffy.cafe.key"
domain full chain certificate "/etc/ssl/mail.puffy.cafe.fullchain.pem"
sign with letsencrypt
}
Now, configure httpd, starting from the OpenBSD example: `cp /etc/examples/httpd.conf /etc/` Edit `/etc/httpd.conf`, we want the first block to match all domains but not "example.com", and we do not need the second block listen on 443/tcp (except if you want to run a https server with some content, but you are on your own then). The resulting file should look like the following:
server "*" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
location * {
block return 302 "https://$HTTP_HOST$REQUEST_URI"
}
}
Enable and start httpd with `rcctl enable httpd && rcctl start httpd`. Run `acme-client -v mail.puffy.cafe` to generate the certificate with some verbose output (if something goes wrong, you will have a clue). If everything went fine, you should have the full chain certificate in `/etc/ssl/mail.puffy.cafe.fullchain.pem` and the private key in `/etc/ssl/private/mail.puffy.cafe.key`. ## Rspamd You will use rspamd to filter spam and sign outgoing emails for DKIM. Install rspamd and the filter to plug it to opensmtpd:
pkg_add rspamd-- opensmtpd-filter-rspamd
You need to configure rspamd to sign outgoing emails with your DKIM private key, to proceed, create the file `/etc/rspamd/local.d/dkim_signing.conf` (the filename is important):
allow_username_mismatch = true;
domain {
puffy.cafe {
path = "/etc/mail/dkim/private/puffy.cafe.key";
selector = "dkim";
}
}
For better performance, you need to use redis as a cache backend for rspamd:
rcctl enable redis
rcctl start redis
Now you can start rspamd:
rcctl enable rspamd
rcctl start rspamd
For extra information about rspamd (like statistics or its web UI), I wrote about it in 2021: => https://dataswamp.org/~solene/2021-07-13-smtpd-rspamd.html Older blog post: 2024-07-13 Filtering spam using Rspamd and OpenSMTPD on OpenBSD ### Alternatives If you do not want to use rspamd, it is possible to replace the DKIM signing part using `opendkim`, `dkimproxy` or `opensmtpd-filter-dkimsign`. The spam filter could be either replaced by the featureful `spamassassin` available as a package, or partially with the base system program `spamd` (it does not analyze emails). This guide only focus on rspamd, but it is important to know alternatives exist. ## OpenSMTPD OpenSMTPD configuration file on OpenBSD is `/etc/mail/smtpd.conf`, here is a working configuration with a lot of comments:
pki puffy.cafe cert "/etc/ssl/mail.puffy.cafe.fullchain.pem"
pki puffy.cafe key "/etc/ssl/private/mail.puffy.cafe.key"
smtp sub-addr-delim '_'
filter rspamd proc-exec "filter-rspamd"
table aliases file:/etc/mail/aliases
listen on all port 25 tls pki "puffy.cafe" filter "rspamd"
listen on all port 465 smtps pki "puffy.cafe" auth mask-src filter "rspamd"
listen on all port 587 tls-require pki "puffy.cafe" auth mask-src filter "rspamd"
action "local" lmtp "/var/dovecot/lmtp" alias <aliases>
action "outbound" relay
match from any for domain "puffy.cafe" action "local"
match from local for local action "local"
match from any auth for any action "outbound"
match from local for any action "outbound"
In addition, you can configure the advertised hostname by editing the file `/etc/mail/mailname`: for instance my machine's hostname is `ryzen` so I need this file to advertise it as `mail.puffy.cafe`. Restart OpenSMTPD with `rcctl restart smtpd`. ### TLS For ports using STARTTLS (25 and 587), there are different options with regard to TLS encryption.
root: solene
It is possible to redirect to multiple users using a comma to separate them, this is handful if you want to create a local group delivering emails to multiple users. Instead of a user, it is possible to append the incoming emails to a file, pipe them to a command or return an SMTP code. The aliases(5) man pages contains all you need to know. => https://man.openbsd.org/aliases.5 OpenBSD manual pages: aliases(5) Every time you modify this file, you need to run the command `smtpctl update table aliases` to reload the aliases table in OpenSMTPD memory. You can add a new email account by creating a new user with a shell preventing login:
useradd -m -s /sbin/nologin username_here
passwd username_here
This user will not be able to do anything on the server but connecting to SMTP/IMAP/POP. They will not be able to change their password either! ### Handling extra domains If you need to handle emails for multiple domains, this is rather simple:
table lambda file:/etc/mail/aliases-lambda
action "local_mail_lambda" lmtp "/var/dovecot/lmtp" alias <lambda>
match from any for domain "lambda-puffy.eu" action "local_mail_lambda"
Note that the users will be the same for all the domains configured on the server. If you want to have separate users per domains, or that "user a" on domain A and "user a" on domain B could be different persons / logins, you would need to setup virtual users instead of using system users. Such setup is beyond the scope of this guide. ### Without Dovecot It is possible to not use Dovecot. Such setup can suit users who would like to download the maildir directory using rsync on their local computer, this is a one-way process and does not allow sharing a mailbox across multiple devices. This reduces maintenance and attack surface at the cost of convenience. This may work as a two-way access (untested) when using a software such as unison to keep both the local and remote directories synchronized, but be prepared to manage file conflicts! If you want this setup, replace the following line in smtpd.conf
action "local" lmtp "/var/dovecot/lmtp" alias <aliases>
by this line: if you want to store the emails into a maildir format (a directory per email folder, a file per email), emails will be stored in the directory "Maildir" in user's homes.
action "local" maildir "~/Maildir/" junk alias <aliases>
or this line if you want to keep the mbox format (a single file with emails appended to it, not practical), the emails will be stored in /var/mail/$user.
action "local" mbox alias <aliases>
=> https://en.wikipedia.org/wiki/Maildir Wikipedia page: Maildir format => https://en.wikipedia.org/wiki/Mbox Wikipedia page: Mbox format ## Dovecot Dovecot is an important piece of software for the domain end users, it provides protocols like IMAP or POP3 to read emails from a client. It is the most popular open source IMAP/POP server available (the other being Cyrus IMAP). Install dovecot with the following command line:
pkg_add dovecot-- dovecot-pigeonhole--
Dovecot has a lot of configuration files in `/etc/dovecot/conf.d/` although most of them are commented and ready to be modified, you will have to edit a few of them. This guide provides the content of files with empty lines / comments stripped so you can quickly check if your file is ok, you can use the command `awk '$1 !~ /^#/ && $1 ~ /./'` on a file to display its "useful" content only (awk will not modify the file). Modify `/etc/dovecot/conf.d/10-ssl.conf` and search the lines `ssl_cert` and `ssl_key`, change their values to your certificate full chain and private key. The file (filtered of all comments/empty lines) should look like the following:
ssl_cert = </etc/ssl/mail.puffy.cafe.fullchain.pem
ssl_key = </etc/ssl/private/mail.puffy.cafe.key
Modify `/etc/dovecot/conf.d/10-mail.conf`, search for a commented line `mail_location`, uncomment it and set the value to `maildir:~/Maildir`, this will tell Dovecot where users mailboxes are stored and in which format, we want to use the maildir format. The resulting file should look like:
mail_location = maildir:~/Maildir
namespace inbox {
inbox = yes
}
mmap_disable = yes
first_valid_uid = 1000
mail_plugin_dir = /usr/local/lib/dovecot
protocol !indexer-worker {
}
mbox_write_locks = fcntl
Modify the file `/etc/dovecot/conf.d/20-lmtp.conf`, LMTP is the protocol used by opensmtpd to transmit incoming emails to dovecot. Search for the commented variable `mail_plugins` and uncomment it with the value `mail_plugins = $mail_plugins sieve`: The resulting file should look like:
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
If you do not want to use IMAP or POP3, you do not need Dovecot. There is an explanation above how to proceed without Dovecot. ### IMAP => https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol Wikipedia page: IMAP protocol IMAP is an efficient protocol that returns headers of emails per directory, so you do not have to download all your emails to view the directory list, emails are downloaded upon read (by default in most email clients). It allows some cool features like server side search, incoming email sorting with sieve filters or multi devices access. Edit `/etc/dovecot/conf.d/20-imap.conf` and configure the last lines accordingly to the result file:
protocol imap {
mail_plugins = $mail_plugins imap_sieve
mail_max_userip_connections = 25
}
The number of connections per user/IP should be high if you have an email client tracking many folders, in IMAP a connection is required for each folder, so the number of connections can quickly increase. On top of that, if you have multiple devices under the same public IP you could quickly reach the limit. I found 25 worked fine for me with 3 devices. ### POP => https://en.wikipedia.org/wiki/Post_Office_Protocol Wikipedia page: POP protocol POP3 is a pretty old protocol that is rarely considered by users, I still consider it a viable alternative to IMAP depending on your needs. A major incentive for using POP is that it downloads all emails locally before removing them from the server. As we have no tooling to encrypt emails stored on remote email servers, POP3 is a must if you want to not leave any email on the server. POP3 does not support remote folders, so you can not use Sieve filters on the server to sort your emails and then download them as-this. A POP3 client downloads the Inbox and then sorts the emails locally. It can support multiple devices under some conditions: if you delete the emails after X days, your devices should synchronize before the emails are removed. In such case they will have all the emails stored locally, but they will not be synced together: if both computers A and B are up-to-date, when deleting an email on A, it will still be in B. There are no changes required for POP3 in Dovecot as the defaults are good enough. ### JMAP For information, a replacement for IMAP called JMAP is in development, it is meant to be better than IMAP in every way and also include calendars and address book management. JMAP Implementations are young but exist, although support in email clients is almost non-existent. For instance, it seems Mozilla Thunderbird is not interested in it, an issue in their bug tracker about JMAP from December 2016 only have a couple of comments from people who would like to see it happening, nothing more. => https://bugzilla.mozilla.org/show_bug.cgi?id=1322991 Issue 1322991: Add support for new JMAP protocol From the JMAP website page listing compatible clients, I only recognized the name "aerc" which is a modern console email client. => https://jmap.io/software.html#clients JMAP project website: clients list ### Sieve (filtering rules) => https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language) Wikipedia page: Sieve Dovecot has a plugin to offer Sieve filters, they are rules applied to received emails going into your mailbox, whether you want to sort them into dedicated directories, mark them read or block some addresses. That plugin is called pigeonhole. You will need Sieve to enable the spam filter learning system when moving emails from/to the Junk folder as it is triggered by a Sieve rule. This improves rspamd Bayes (a method using tokens to understand information, the story of the person behind it is interesting) filter ability to detect spam accurately. Edit `/etc/dovecot/conf.d/90-plugin.conf` with the following content:
plugin {
sieve_plugins = sieve_imapsieve sieve_extprograms
# From elsewhere to Spam folder
imapsieve_mailbox1_name = Spam
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:/usr/local/lib/dovecot/sieve/report-spam.sieve
# From Spam folder to elsewhere
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Spam
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:/usr/local/lib/dovecot/sieve/report-ham.sieve
sieve_pipe_bin_dir = /usr/local/lib/dovecot/sieve
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
}
This piece of configuration was taken from the official Dovecot documentation: https://doc.dovecot.org/configuration_manual/howto/antispam_with_sieve/ . It will trigger shell scripts calling rspamd to make it learn what does a spam look like, and what is legit (ham). One script will run when an email is moved out of the spam directory (ham), another one when an email is moved to the spam directory (spam). Modify `/etc/dovecot/conf.d/15-mailboxes.conf` to add the following snippet inside the block `namespace inbox { ... }`, it will associate the Junk directory as the folder containing spam and automatically create it if it does not exist:
mailbox Spam {
auto = create
special_use = \Junk
}
To make this work completely, you need to write the two extra sieve filters that will run trigger the scripts: Create `/usr/local/lib/dovecot/sieve/report-spam.sieve`
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-learn-spam.sh" [ "${username}" ];
Create `/usr/local/lib/dovecot/sieve/report-ham.sieve`
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "${1}";
}
if string "${mailbox}" "Trash" {
stop;
}
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-learn-ham.sh" [ "${username}" ];
Create `/usr/local/lib/dovecot/sieve/sa-learn-ham.sh`
exec /usr/local/bin/rspamc -d "${1}" learn_ham
Create `/usr/local/lib/dovecot/sieve/sa-learn-spam.sh`
exec /usr/local/bin/rspamc -d "${1}" learn_spam
Make the two scripts executable with `chmod +x /usr/local/lib/dovecot/sieve/sa-learn-spam.sh /usr/local/lib/dovecot/sieve/sa-learn-ham.sh`. Run the following command to compile the sieve filters:
sievec /usr/local/lib/dovecot/sieve/report-spam.sieve
sievec /usr/local/lib/dovecot/sieve/report-ham.sieve
### Manage Sieve By default, Sieves rules are a file located on the user home directory, however there is a standard protocol named "managesieve" to manage Sieve filters remotely from an email client. It is enabled out of the box in Dovecot configuration, although you need to make sure you open the port 4190/tcp in the firewall if you want to allow users to use it. ### Start the service Once you configured everything, make sure that dovecot service is enabled, and then start / restart it:
rcctl enable dovecot
rcctl start dovecot
# Webmail A webmail will allow your users to read / send emails from a web interface instead of having to configure a local email client. While they can be convenient, they enable a larger attack surface and are often affected by vulnerability issues, you may prefer to avoid webmail on your server. The two most popular open source webmail are Roundcube mail and Snappymail (a fork of the abandoned rainloop) and Roundcube, they both have pros and cons. ## Roundcube mail setup Roundcube is packaged in OpenBSD, it will pull in all required dependencies and occasionally receive backported security updates. Install the package:
pkg_add roundcubemail
When installing the package, you will be prompted for a database backend for PHP. If you have one or two users, I highly recommend choosing SQLite as it will work fine without requiring a running daemon, thus less maintenance and server resources locked. If you plan to have a lot of users, there are no wrong picks between MySQL or PostgreSQL, but if you already have one of them running it would be better to reuse it for Roundcube. Specific instructions for installing Roundcube are provided by the package README in `/usr/local/share/doc/pkg-readmes/roundcubemail`. We need to enable a few PHP modules to make Roundcube mail working:
ln -s /etc/php-8.2.sample/zip.ini /etc/php-8.2/
ln -s /etc/php-8.2.sample/intl.ini /etc/php-8.2/
ln -s /etc/php-8.2.sample/opcache.ini /etc/php-8.2/
ln -s /etc/php-8.2.sample/pdo_sqlite.ini /etc/php-8.2/
Note that more PHP modules may be required if you enable extra features and plugins in Roundcube. PHP is ready to be started:
rcctl enable php82_fpm
rcctl start php82_fpm
Add the following blocks to `/etc/httpd.conf`, make sure you opened the port 443/tcp in your `pf.conf` and that you reloaded it with `pfctl -f /etc/pf.conf`:
server "mail.puffy.cafe" {
listen on egress tls
tls key "/etc/ssl/private/mail.puffy.cafe.key"
tls certificate "/etc/ssl/mail.puffy.cafe.fullchain.pem"
root "/roundcubemail"
directory index index.php
location "*.php" {
fastcgi socket "/run/php-fpm.sock"
}
}
types {
include "/usr/share/misc/mime.types"
}
Restart httpd with `rcctl restart httpd`. You need to configure Roundcube to use a 24 bytes security key and configure the database: edit the file `/var/www/roundcubemail/config/config.inc.php`: Search for the variable `des_key`, replace its value by the output of the command `tr -dc [:print:] < /dev/urandom | fold -w 24 | head -n 1` which will generate a 24 byte random string. If the string contains a quote character, either escape this character by prefixing it with a `\` or generate a new string. For the database, you need to search the variable `db_dsnw`. If you use SQLite, change this line
$config['db_dsnw'] = 'sqlite:///roundcubemail/db/sqlite.db?mode=0660';
by this line:
$config['db_dsnw'] = 'sqlite:///db/sqlite.db?mode=0660';
If you chose MySQL/MariaDB or PostgreSQL, modify this line:
$config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
by
$config['db_dsnw'] = 'mysql://USER:PASSWORD@DATABASE_NAME';
Where `USER`, `PASSWORD` and `DATABASE_NAME` must match a new user and database created into the backend. Because PHP is chrooted on OpenBSD and that the OpenSMTPD configuration enforces TLS on port 587, it is required to enable TLS to work in the chroot:
mkdir -p /var/www/etc/ssl
cp -p /etc/ssl/cert.pem /etc/ssl/openssl.cnf /var/www/etc/ssl/
To make sure the files `cert.pem` and `openssl.cnf` stay in sync after upgrades, add the two commands to a file `/etc/rc.local` and make this file executable. This script always starts at boot and is the best place for this kind of file copy. If your IMAP and SMTP hosts are not on the same server where Roundcube is installed, adapt the variables `imap_host` and `smtp_host` to the server name. If Roundcube mail is running on the same server where OpenSMTPD is running, you need to disable certificate validation because `localhost` will not match the certificate and authentication will fail. Change `smtp_host` line to `$config['smtp_host'] = 'tls://127.0.0.1:587';` and add this snippet to the configuration file:
$config['smtp_conn_options'] = array(
'ssl' => array('verify_peer' => false, 'verify_peer_name' => false),
'tls' => array('verify_peer' => false, 'verify_peer_name' => false));
From here, Roundcube mail should work when you load the domain configured in `httpd.conf`. For a more in-depth guide to install and configure Roundcube mail, there is an excellent guide available which was written by Bruno Flückiger: => https://www.bsdhowto.ch/roundcube.html Install Roundcube on OpenBSD # Hardening It is always possible to improve the security of this stack, all the following settings are not mandatory, but they can be interesting depending on your needs. ## Always allow the sender per email or domain It is possible to configure rspamd to force it to accept emails from a given email address or domain, bypassing the anti-spam. To proceed, edit the file `/etc/rspamd/local.d/multimap.conf` to add this content:
local_wl_domain {
type = "from";
filter = "email:domain";
map = "$CONFDIR/local.d/whitelist_domain.map";
symbol = "LOCAL_WL_DOMAIN";
score = -10.0;
description = "domains that are always accepted";
}
local_wl_from {
type = "from";
map = "$CONFDIR/local.d/whitelist_email.map";
symbol = "LOCAL_WL_FROM";
score = -10.0;
description = "email addresses that are always accepted";
}
Create the files `/etc/rspamd/local.d/whitelist_domain.map` and `/etc/rspamd/local.d/whitelist_email.map` using the command `touch`. Restart the service rspamd with `rcctl restart rspamd`. The created files use a simple syntax, add a line for each entry you want to allow:
10 4 * * 0 -s acme-client mail.puffy.cafe && rcctl restart dovecot httpd smtpd
This will try to renew the certificate for `mail.puffy.cafe` every Sunday at 04h10 and upon renewal restart the services using the certificate: dovecot, httpd and smtpd. ## All about logs If you need to find some logs, here is a list of paths where to find information:
/var/log/rspamd/rspamd.log 600 7 500 * Z "pkill -USR1 -u root -U root -x rspamd"
/var/www/roundcubemail/logs/errors.log 600 7 500 * Z
/var/www/roundcubemail/logs/sendmail.log 600 7 500 * Z
## Disk space Finally, OpenSMTPD will stop delivering emails locally if the `/var` partition has less than 4% of free disk space, be sure to monitor the disk space of this partition otherwise you will not receive emails anymore for a while before noticing something is wrong. # Conclusion Congratulations, you configured a whole email stack that will allow you to send emails to the world, using your own domain and hardware. Keeping your system up to date is important as you have network services exposed to the wild Internet. Even with a properly configured setup featuring SPF/DKIM/DMARC/PTR, it is not guaranteed to not end in the spam directory of our recipients. The IP reputation of your SMTP server also account, and so is the domain name extension (I have a `.pw` domain which I learned too late that it was almost always considered as spam because it is not mainstream). </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/openbsd-email-server-setup.gmi</guid> <link>gemini://perso.pw/blog//articles/openbsd-email-server-setup.gmi</link> <pubDate>Thu, 25 Jul 2024 00:00:00 GMT</pubDate> </item> <item> <title>Cloud gaming review: Xbox xCloud and Amazon Luna+</title> <description> <![CDATA[ <pre># Introduction There are not many cloud gaming services around, here is a quick summary of Xbox Gaming and Amazon Luna services. # Xbox Cloud Gaming (Microsoft) The Xbox Cloud gaming service is available for Xbox Game Pass Ultimate subscribers at a price of 17.99$€ / month. ## pros
CONFIG=/etc/wireguard/my-vpn.conf
mkdir -p /etc/netns/vpn/
ip netns exec vpn ip l del tun0
ip netns del vpn
DNS=$(awk '/^DNS/ { print $3 }' $CONFIG)
IP=$(awk '/^Address/ { print $3 }' $CONFIG)
echo "nameserver $DNS" > /etc/netns/vpn/resolv.conf
ip netns add vpn
ip -n vpn link set lo up
ip link add tun0 type wireguard
ip link set tun0 netns vpn
ip netns exec vpn wg setconf tun0 <(wg-quick strip "$CONFIG")
ip -n vpn a add "$IP" dev tun0
ip -n vpn link set tun0 up
ip -n vpn route add default dev tun0
ip -n vpn add
This script autoconfigure the network namespace and the VPN interface + the DNS server to use. There are extra checks at the end of the script that you can uncomment if you want to take a look at the public IP and DNS resolver used just after connection. Running this script will make the netns "vpn" available for use. The command to run a program under the namespace is `ip netns exec vpn your command`, it can only be run as root. ## Sudo rule Now you need a specific rule so you can use sudo to run a command in vpn netns as your own user without having to log in as root. Add this to your sudo configuration file, in my example I allow the user `solene` to run commands as `solene` for the netns vpn:
solene ALL=(root) NOPASSWD: /usr/sbin/ip netns exec vpn /usr/bin/sudo -u solene -- *
When using this command line, you MUST use full paths exactly as in the sudo configuration file, this is important otherwise it would allow you to create a script called `ip` with whatever commands and run it as root, while `/usr/sbin/ip` can not be spoofed by a local script in $PATH. If I want a shell session with the VPN, I can run the following command:
sudo /usr/sbin/ip netns exec vpn /usr/bin/sudo -u solene -- bash
This runs bash under the netns vpn, so any command I'm running from it will be using the VPN. # Limitations It is not a real limitation, but you may be caught by it, if you make a program listening on localhost in the netns vpn, you can only connect to it from another program in the same namespace. There are methods to connect two namespaces, but I do not plan to cover it, if you need to search about this setup, it can be done using socat (this is explained in the blog post linked earlier) or a local bridge interface. # Conclusion Network namespaces are a cool feature on Linux, but it is overly complicated in my opinion, unfortunately I have to deal with it, but at least it is working fine in practice. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/linux-vpn-netns.gmi</guid> <link>gemini://perso.pw/blog//articles/linux-vpn-netns.gmi</link> <pubDate>Thu, 04 Jul 2024 00:00:00 GMT</pubDate> </item> <item> <title>The Old Computer Challenge v4 (Olympics edition)</title> <description> <![CDATA[ <pre># Introduction This is the time of the year where I announce the Old Computer Challenge (OCC) date. I recommend visiting the community website about the OCC if you want to connect with the community. => https://occ.deadnet.se/ Old Computer Challenge community => https://dataswamp.org/~solene/tag-oldcomputerchallenge.html The Old Computer Challenge history => static/occ-v4.jpg The Old Computer Challenge v4 poster, by @prahou@merveilles.town on Mastodon # When? The Old Computer Challenge 4th edition will begin 13th July to 20th July 2024. It will be the prequel to Olympics, I was not able to get the challenge accepted there so we will do it our way. # How to participate? While the three previous editions had different rules, I came to agree with the community for this year. Choose your rules! When I did the challenge for the first time, I did not expect it to become a yearly event nor that it would gather aficionados during the trip. The original point of the challenge was just to see if I could use my oldest laptop as my main computer for a week, there were no incentive, it was not a contest and I did not have any written rules. Previous editions rules were about using an old laptop, use a computer with limited hardware (and tips to slow down a modern machine) or limit Internet access to a single hour per day. I always insist on the fact it should not hinder your job, so people participating do not have to "play" during work. Smartphones became complicated to handle, especially with the limited Internet access, all I can recommend to people is to define some rules you want to stick to, and apply to it the best you can. If you realllyyyy need once to use a device that would break the rules, so be it if it is really important, nobody will yell at you. People doing the OCC enjoy it for multiple reasons, find yours! Some find the opportunity to disconnect a bit, change their habit, do some technoarcheology to run rare hardware, play with low-tech, demonstrate obsolescence is not a fatality etc... Some ideas if you do not know what to do for the challenge:
vnconfig vnd0 /path/to/file.iso
This will create a new device `/dev/vnd0`, now you can mount it on your file-system with:
mount -t cd9660 /dev/vnd0c /mnt
You should be able to browser your iso file content in /mnt at this point. # Unmounting If you are done with the file, you have to umount it with `umount /mnt` and destroy the vnd device using `vnconfig -u vnd0`. # Going further: Using a file as an encrypted disk If you want to use a single file as a file system, you have to provision the file with disk space using the command `dd`, you can fill it with zeroes but if you plan to use encryption on top of it, it's better to use random data. In the following example, you will create a file `my-disk.img` of a size of 10 GB (1000 x 10 MB):
dd if=/dev/random of=my-disk.img bs=10M count=1000
Now you can use vnconfig to expose it as a device:
vnconfig vnd0 my-disk.img
Finally, the command `bioctl` can be used to configure encryption on the disk, `disklabel` to partition it and `newfs` to format the partitions. You can follow OpenBSD FAQ guides, make sure use the the device name `/dev/vnd0` instead of wd0 or sd0 from the examples. => https://www.openbsd.org/faq/faq14.html#softraidCrypto OpenBSD FAQ: Encrypting external disk </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/mount-iso-file-openbsd.gmi</guid> <link>gemini://perso.pw/blog//articles/mount-iso-file-openbsd.gmi</link> <pubDate>Tue, 18 Jun 2024 00:00:00 GMT</pubDate> </item> <item> <title>OpenBSD extreme privacy setup</title> <description> <![CDATA[ <pre># Introduction This blog post explains how to configure an OpenBSD workstation with extreme privacy in mind. This is an attempt to turn OpenBSD into a Whonix or Tails alternative, although if you really need that level of privacy, use a system from this list and not the present guide. It is easy to spot OpenBSD using network fingerprinting, this can not be defeated, you can not hide the fact you use OpenBSD to network operators. I did this guide as a challenge for fun, but I also know some users have a use for this level of privacy. Note: this guide explains steps related to increase privacy of OpenBSD and its base system, it will not explain how to configure a web browser or how to choose a VPN. # Checklist OpenBSD does not have much network activity with a default installation, but the following programs generate traffic:
127.0.0.9 firmware.openbsd.org
## Packages, firmware and mirrors The firmware installation and OpenBSD mirror configuration using Tor and I2P are covered in my previous article, it explains how to use tor or i2p to download firmware, packages and system sets to upgrade. => https://dataswamp.org/~solene/2024-05-25-openbsd-privacy-friendly-mirror.html OpenBSD privacy-friendly mirrors There is a chicken / egg issue with this though, on a fresh install you have neither tor nor i2p, so you can not download tor or i2p packages through it. You could download the packages and their dependencies from another system and install them locally using USB. Wi-Fi and some other devices requiring a firmware may not work until you run fw_update, you may have to download the files from another system and pass the network interface firmware over a USB memory stick to get network. A smartphone with USB tethering is also a practical approach for downloading firmware, but you will have to download it over clearnet. ## DNS DNS is a huge topic for privacy-oriented users, I can not really recommend a given public DNS servers because they all have pros and cons, I will use 1.1.1.1 and 9.9.9.9 for the example, but use your favorite DNS. Enable the daemon unwind, it is a local DNS resolver with some cache, and supports DoT, DoH and many cool features. Edit the file `/etc/unwind.conf` with this configuration:
forwarder { 1.1.1.1 9.9.9.9 }
As I said, DoT and DoH is supported, you can configure it directly in the forwarder block, the man page explains the syntax: => https://man.openbsd.org/unwind.conf OpenBSD manual pages: unwind.conf Now, enable, start and make sure the service is running fine:
rcctl enable unwind
rcctl start unwind
rcctl check unwind
A program named `resolvd` is running by default, when it finds that unwind is running, resolvd modifies `/etc/resolv.conf` to switch DNS resolution to 127.0.0.1, so you do not have anything to do. ## Firewall configuration A sane firewall configuration for workstations is to block all incoming connections. This can be achieved with the following `/etc/pf.conf`: (reminder, last rule matches)
set block-policy drop
set skip on lo
match in all scrub (no-df random-id max-mss 1440)
antispoof quick for egress
block
pass out quick inet
pass out quick inet6
pass in proto icmp
Reload the rules with `pfctl -f /etc/pf.conf`. ## Network configuration Everything is ready so you can finally enable networking. You can find a list of network interfaces with `ifconfig`. Create the hostname.if file for your network device. => https://man.openbsd.org/hostname.if OpenBSD manual pages: hostname.if An ethernet device configuration using DHCP would look like this
inet autoconf
A wireless device configuration would look like this:
join SSID_NAME wpakey password1
join OTHER_NET wpakey hunter2
inet autoconf
You can randomize your network device MAC address at each boot by adding the line `lladdr random` to its configuration file. Start the network with `sh /etc/netstart ifname`. # Special attention during updates When you upgrade your OpenBSD system from a release to another or to a newer snapshot using `sysupgrade`, the command `fw_update` will automatically be run at the very end of the installer. It will bypass any `/etc/hosts` changes as it runs from a mini root filesystem, if you do not want `fw_update` to be used over clearnet at this step, the only method is to disable network at this step, which can be done by using `sysupgrade -n` to prepare the upgrade without rebooting, and then:
mv /etc/hostname.* /root/
sysupgrade -n
echo 'mv /root/hostname.* /etc/' > /etc/rc.firsttime
echo 'sh /etc/netstart' >> /etc/rc.firsttime
chmod +x /etc/rc.firsttime
reboot
It will move all your network configuration in `/root/`, run sysupgrade, and configure the next boot to restore the hostname files back to place and start the network. # Webcam and Microphone protection By default, OpenBSD "filters" webcam and microphone use, if you try to use them, you get a video stream with a black background and no audio on the microphone. This is handled directly by the kernel and only root can change this behavior. To toggle microphone recording, change the sysctl `kern.audio.record` to 1 or 0 (default). To toggle webcam recording, change the sysctl `kern.video.record` to 1 or 0 (default). What is cool with this mechanism is it makes software happy when they make webcam/microphone a requirement, they exist but just record nothing. # Conclusion Congratulations, you achieved a high privacy level with your OpenBSD installation! If you have money and enough trust in some commercial services, you could use a VPN instead (or as a base) of Tor/I2P, but it is not in the scope of this guide. I did this guide after installing OpenBSD on a laptop connected to another laptop doing NAT and running Wireshark to see exactly what was leaking over the network. It was a fun experience. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/openbsd-privacy-setup.gmi</guid> <link>gemini://perso.pw/blog//articles/openbsd-privacy-setup.gmi</link> <pubDate>Mon, 10 Jun 2024 00:00:00 GMT</pubDate> </item> <item> <title>OpenBSD mirror over Tor / I2P</title> <description> <![CDATA[ <pre># Introduction For an upcoming privacy related article about OpenBSD I needed to setup an access to an OpenBSD mirror both from a Tor hidden service and I2P. The server does not contain any data, it only act as a proxy fetch files from a random existing OpenBSD mirror, so it does not waste bandwidth mirroring everything, the server does not have the storage required anyway. There is a little cache to keep most requested files locally. => https://en.wikipedia.org/wiki/I2P Wikipedia page about I2P protocol => https://en.wikipedia.org/wiki/The_Tor_Project Wikipedia page about Tor It is only useful if you can not reach OpenBSD mirrors, or if you really need to hide your network activity. Tor or I2P will be much slower than connecting to a mirror using HTTP(s). However, as they exist now, let me explain how to start using them. # Tor Using a client with tor proxy enabled, you can reach the following address to download installers or sets. => http://kdzlr6wcf5d23chfdwvfwuzm6rstbpzzefkpozp7kjeugtpnrixldxqd.onion/pub/OpenBSD/ OpenBSD onion mirror over Tor If you want to install or update your packages from tor, you can use the onion address in `/etc/installurl`. However, it will not work for sysupgrade and syspatch, and you need to export the variable `FETCH_CMD="/usr/local/bin/curl -L -s -q -N -x socks5h://127.0.0.1:9050"` in your environment to make `pkg_*` programs able to use the mirror. To make sysupgrade or syspatch able to use the onion address, you need to have the program `torsocks` installed, and patch the script to use torsocks:
[MIRROR]
type = client
address = 127.0.0.1
port = 8080
destination = 2st32tfsqjnvnmnmy3e5o5y5hphtgt4b2letuebyv75ohn2w5umq.b32.i2p
destinationport = 8081
keys = mirror.dat
Now, enable and start i2pd with `rcctl enable i2pd && rcctl start i2pd`. After a few minutes to let i2pd establish tunnels, you should be able to browse the mirror over i2p using the address `http://127.0.0.1:8080/`. You can configure the port 8080 to another you prefer by modifying the file `tunnels.conf`. You can use the address `http://127.0.0.1:8080/pub/OpenBSD/` in `/etc/installurl` to automatically use the I2P mirror for installing/updating packages, or keeping your system up to date with syspatch/sysupgrade. Note: from experience the I2P mirror works fine to install packages, but did not play well with fw_update, syspatch and sysupgrade, maybe because they use ftp command that seems to easily drop the connection. Downloading the files locally using a proper HTTP client supporting transfer resume would be better. On the other hand, this issue may be related to the current attack the I2P network is facing as of the time of writing (May 2024). # Firmware mirror OpenBSD pulls firmware from a different server than the regular mirrors, the address is `http://firmware.openbsd.org/firmware/`, the files on this server are signed packages, they can be installed using `fw_update $file`. Both i2p and tor hidden service hostname can be reused, you only have to change `/pub/OpenBSD/` by `/firmware/` to browse the files. The proxy server does not cache any firmware, it directly proxy to the genuine firmware web server. They are on a separate server for legal matter, it seems to be a grey area. ## Disable firmware.openbsd.org For maximum privacy, you need to neutralize `firmware.openbsd.org` DNS lookup using a hosts entry. This is important because `fw_update` is automatically used after a system upgrade (as of 2024). In `/etc/hosts` add the line:
127.0.0.9 firmware.openbsd.org
The IP in the snippet above is not a mistake, it will avoid fw_update to try to connect to a local web server if any. ## Tor access If you use tor, it is complicated to patch `fw_update` to use torsocks, the best method is to download the firmware manually. => http://kdzlr6wcf5d23chfdwvfwuzm6rstbpzzefkpozp7kjeugtpnrixldxqd.onion/firmware/ Firmware onion address ## I2P access If you use i2p, you can reuse the tunnel configuration described in the I2P section, and pass the full url to `fw_update`:
fw_update -p http://127.0.0.1:8080/firmware/$(uname -r)/
fw_update -p http://127.0.0.1:8080/firmware/snapshots/
Or you can browse the I2P url using an http client with the i2p proxy to download the firmware manually. => http://2st32tfsqjnvnmnmy3e5o5y5hphtgt4b2letuebyv75ohn2w5umq.b32.i2p:8081/firmware/ Firmware i2p address # Conclusion There were no method to download OpenBSD files over Tor and I2P for people really needing it, it is now a thing. If you encounter issues with the service, please let me know. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/openbsd-privacy-friendly-mirror.gmi</guid> <link>gemini://perso.pw/blog//articles/openbsd-privacy-friendly-mirror.gmi</link> <pubDate>Sat, 25 May 2024 00:00:00 GMT</pubDate> </item> <item> <title>Improve your SSH agent security</title> <description> <![CDATA[ <pre># Introduction If you are using SSH quite often, it is likely you use an SSH agent which stores your private key in memory so you do not have to type your password every time. This method is convenient, but it comes at the expense of your SSH key use security, anyone able to use your session while the agent holds the key unlocked can use your SSH key. This scenario is most likely to happen when using a compromised build script. However, it is possible to harden this process at a small expense of convenience, make your SSH agent ask for confirmation every time the key has to be used. # Setup The tooling provided with OpenSSH comes with a simple SSH agent named `ssh-agent`. On OpenBSD, the agent is automatically started and ask to unlock your key upon graphical login if it finds a SSH key in the default path (like `~/.ssh/id_rsa`). Usually, the method to run the ssh-agent is the following. In a shell script defining your environment at an early stage, either your interactive shell configuration file or the script running your X session, you use `eval $(ssh-agent -s)`. This command runs ssh-agent and also enable the environment variables to make it work. Once your ssh-agent is correctly configured, it is required to add a key into it, now, here are two methods to proceed. ## OpenSSH ssh-add In addition to ssh-agent, OpenSSH provides ssh-add to load keys into the agent. It is simple of use, just run `ssh-add /path/to/key`. => https://man.openbsd.org/ssh-add ssh-add manual page If you want to have a GUI confirmation upon each SSH key use, just add the flag `-c` to this command line: `ssh-add -c /path/to/key`. In OpenBSD, if you have your key at a standard location, you can modify the script `/etc/X11/xenodm/Xsession` to change the first occurrence of `ssh-add` by `ssh-add -c`. You will still be greeting for your key password upon login, but you will be asked for each of its use. ## KeepassXC It turns out the password manager KeepassXC can hold SSH keys, it works great for having used for a while. KeepassXC can either store the private key within its database or load a private key from the filesystem using a path and unlock it using a stored password, the choice is up to you. You need to have the ssh-agent variables in your environment to have the feature work, as KeepassXC will replace ssh-add only, not the agent. KeepassXC documentation has a "SSH Agent integration" section explaining how it works and how to configure it. => https://keepassxc.org/docs/ KeepassXC official documentation In the key settings and "SSH Agent" tab, there is a checkbox to ask user confirmation upon each key use. # Other security features ## Timeout I would recommend to automatically delete the key from the agent after some time, this is especially useful if you do not actively use your SSH key. In `ssh-add`, this can be achieved using `-t time` flag (it's tea time, if you want to remember about it), where time is a number of seconds or a time format specified in sshd_config, like 5s for 5 seconds, 10m for 10 minutes, 16h for 16 hours or 2d for 2 days. In KeepassXC, it's in the key settings, within the SSH agent tab, you can configure the delay before the key is removed from the agent. # Conclusion The ssh-agent is a practical software that ease the use of SSH keys without much compromise with regards to security, but some extra security could be useful in certain scenarios, especially for developers running untrusted code as their user holding the SSH key. While the extra confirmation could still be manipulated by a rogue script, it would come with a greater complexity at the cost of being spotted more easily. If you really want to protect your SSH keys, you should use them from a hardware token requiring a physical action to unlock it. While I find those tokens not practical and expensive, they have their use and they can not be beaten by a pure software solution. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/ssh-agent-security-enhancement.gmi</guid> <link>gemini://perso.pw/blog//articles/ssh-agent-security-enhancement.gmi</link> <pubDate>Mon, 27 May 2024 00:00:00 GMT</pubDate> </item> </channel> </rss>