# Manage your server Once your server running, you must make sure everything works fine. Do not read any further if you don't plan to maintain it. Luckily, OpenBSD developpers made such tasks easier. ## Daily reports Every day (actually every night) a report from "Charlie Root" is generated and mailed to "root" user. Inside, you can find: * Space remaining on disk * What file has been modified and what changed. If you didn't edit them, there might be a problem. * New installed packages. * ... It look like this: ``` Running security(8): Checking mailbox ownership. user spamd.black mailbox is owned by root user spamd.black mailbox is -rw-r--r--, group wheel ====== /etc/rc.local diffs (-OLD +NEW) ====== --- /var/backups/etc_rc.local.current Sat Jun 4 03:46:48 2016 +++ /etc/rc.local Thu Oct 20 09:46:54 2016 @@ -1 +1 @@ -su pi -c "tmux new -s rtorrent -d rtorrent" +/usr/bin/su pi -c "/usr/bin/tmux new -s rtorrent -d /usr/local/bin/rtorrent" ====== /etc/spwd.db SHA-256 checksums ====== OLD: 075455a721ef[...]b942f590fb8e3edfd88c5dd4 NEW: 37eba7537dd7[...]42468cc4cbe768fcf496b230 ``` You can read warning about file owners and changes made in a file. Lines starting with "+" were added, those starting with a "-" removed. In this example, at last, a checksum on the password database has changed: did you add a new user? For more information, read man security(8). > Well, that's nice, but how do I get it? As you will see, it's very easy : 1. Edit /etc/mail/aliases ; 2. Add at the bottom : ``` root : toto@ouaf.xyz ``` Of course, replace with a mail address you read daily. Then, run ``` # newaliases ``` That's it! π Just to make sure, send yourself a test message : ``` echo "Hello sweetie!" | mail -s "test" root ``` You should get this mail at the address written in /etc/mail/aliases. Now, it's up to you to read these report every day. π If you need to, you can change the domain name of the sender if you edit /etc/mail/mailname. As example : ``` athome.tld ``` Doing so, mails sent by "root" will have the "From:" field set to "root@athome.tld" which might be of interest if you fear spam. ### File system check Add this line to /etc/daily.local to check filesystems every day : ``` CHECKFILESYSTEMS=1 ``` Read man 8 daily to learn more π (HTM) https://man.openbsd.org/daily ## The Firewall (pf) > The firewall? Already ? Absolutely. You want to keep your fresh system safe, don't you? We'll start with simple examples and suggest a few more for thoses interested. On OpenBSD, the firewall is pf as in "packet filter". It is configured in /etc/pf.conf. You will see, its syntax is easy to understand. First, you have to ask yourself what do you need. A web server (http)? Mail server? Depending on your answers, you won't open the same port number. We actually will close every port except the ones you really need. To find the ports on which services listen, look at the contents of /etc/services. Thus, writing "www" or "80" is the same for pf, but is more readable for humans. The rules you will define will be applied in the order they are written. This means next rules can override previous ones β . To keep a rule state, use "match" instead of "pass" or "block". To apply directly a rule without looking forward, use "quick" keyword. You'll see, it's quite easy actually π. Read the official PF's user guide to go further. (HTM) https://www.openbsd.org/faq/pf/index.html ### A first example for pf Ready? Let's go for a detailed but simple example. We are going to configure the firewall for a website with access on ports 80 (www) and 443 (https). We start by blocking everything, and record the prohibited connections with the word "log". ``` block log ``` To make our life easier, we are going to write the ports to open in a variable. This will be particularly practical to add more ports to manage later. ``` tcp_pass = "{ 80 443 }" ``` Note that this is identical to: ``` tcp_pass = "{ www https } ``` Then, we allow potential visitors to access your server. These will be so-called "incoming" connections, so we will use the "in" keyword. Instead of looking for the name of your network interface (which depends on your hardware), we will specify the name of the group that these interfaces belongs to so that it works without worry: "egress". ``` pass in on egress proto tcp to port $tcp_pass ``` > You're cute eh, but that's all gibberish! Okay, we'll explain what this syntax means. We can translate the previous configuration line as follows: "let pass inward (pass in) through the egress interfaces (on egress) for the tcp protocol (proto tcp) to the ports in tcp_pass (to port $tcp_pass). Fiew! π I suggest to allow ping response. To do so, let icmp protocol in: ``` pass in proto icmp ``` Finally, we allow all the output traffic (keyword "out"): ``` pass out ``` Finally : ``` tcp_pass = "{80,443}" block log pass in proto icmp pass in on egress proto tcp to port $tcp_pass pass out ``` Easy, right? π As you can see pf give us a fine control on our server. At first, you'll just want to choose which ports should be opened. This makes a lot of new concepts, take the time to read again what has been written so far if necessary. When you are more comfortable, know that we can filter incoming and outgoing traffic, and even redirect part of it to internal services (i.e. anti-spam). In the next part, we introduce fun and useful concepts to make the most of pf. You will see how to ignore certain lists of IPs known as harmful that will be recorded in tables, rules against bruteforce attacks or even a proposed tool that adds potential attackers to the blacklist in real time. I let you build your /etc/pf.conf file according to your needs. Start from the example seen above then add the ports to open. Do not hesitate to consult the example provided at the end of this document. > To be sure, can we have an example to open the SSH port? If the configured SSH port is 22 as default, then you will have in the pf configuration: ``` pass in on egress proto tcp to port 22 ``` Of course, you can also just change the tcp_pass variable: ``` tcp_pass = "{80 443 22}" pass in ... ``` ### Convenient commands for pf Find below suggestions of useful commands to manage pf: * Disable the firewall: # pfctl -d * Activate the firewall with the /etc/pf.conf file: # pfctl -ef /etc/pf.conf * Restart the firewall: # pfctl -d && pfctl -ef /etc/pf.conf * Reload the firewall configuration: # pfctl -f /etc/pf.conf * Empty the firewall rules (β Warning!), it can be useful when you self-ban yourself from the server (yes, it happens even to the best ... :-?): # pfctl -F all * See in real time what the firewall is blocking (assuming you wrote the "log" keyword in the configuration): # tcpdump -n -e -ttt -i pflog0 * View the saved logs at any time: # tcpdump -n -e -ttt -r /var/log/pflog * Display the list of blocked IPs in a table: # pfctl -t table_name -T show * Add an IP in a table: # pfctl -t name_of_the_table -T add 123.456.678.909 * Remove an IP from a table # pfctl -t table_name -T delete 123.456.678.909 * List all active rules: # pfctl -sr ### IP lists to blacklist #### pf-badhost Some IPs are known to be harmful. Between those that scan for an open port or those that attempt bruteforce attacks, the list goes on. Fortunately, we can configure the firewall so that it completely ignores these IPs and thus protect and lighten the load on our server. This is what allows the pf-badhost project. (HTM) https://www.geoghegan.ca/pfbadhost.html #### Author's blacklists I keep up to date lists of IP who recentrly tried bad stuff on my server. Feel free to use them! π (DIR) /evils/ ### Anti-Bruteforce #### pf detection One method hackers use to attack a server is called "bruteforce". Such attacks consist of trying all possible username / password combinations until they find the correct one. If you choosed strong passphrases, you should be safe. However, these attacks monopolize your server's resources and can potentially succeed one day (admit that it would be bad luck). In order to thwart these attacks, you should take the time to analyze the logs of the services you host (in /var/log and /var/www/logs) for identification failures and notice where these attacks are coming from to banish the source. But let's be honest, it's both painful and time consuming. Ideally, a tool that monitors logs for you and takes care of blacklisting "attacker" IPs on your firewall. To do so, you can use nono or sshguard which are discussed later. nono: (DIR) /code/nono.awk/ sshguard: (HTM) https://www.sshguard.net/ In the meantime, pf already integrates a protection which limits the number of connections on a port during a given time. It is very effective and remains light. Read the next paragraph π. pf has a very interesting feature: "tables". This will allow us to remember certain IP addresses of hackers who would try to compromise the server. For example, to protect the SSH service, we will proceed as follows: 1. Create a table to record abusive IPs with our SSH server. 2. Block all the IPs that would be in the previous table, and do not go further for them. 3. Open the ssh port, but record in the previous table all the IPs that attempt to connect more than 3 times per minute (bruteforce attack). So that gives us this: ``` table <ssh_abuse> persist block in log quick proto tcp from <ssh_abuse> to any port ssh pass in on egress proto tcp to any port $ssh_port modulate state \ (source-track rule, \ max-src-conn-rate 3/60, \ overload <ssh_abuse> flush global) ``` With the keyword quick, further rules won't be read so abuser is blocked and that's it. Here is another example for a website (http and https ports): ``` http_ports = "{www https}" # If more than 40 connections every 5 seconds on the http (s) ports # or if she tries to connect more than 100 times # we add the ip to block it. pass in on egress proto tcp to any port $http_ports modulate state \ (source-track rule, \ max-src-conn 100, max-src-conn-rate 40/5,\ overload <http_abuse> flush global) ``` #### nono For once, I suggest a little tool I wrote to blacklist IP when their behaviour is suspicious. It doesn't need anything except what's already in OpenBSD's base. To learn more about it, see nono : say "no no" to intruders. (BIN) /code/nono.awk #### sshguard Contrary to what its name suggests, sshguard is able to check connection attempts on multiple services, not just SSH. (HTM) https://www.sshguard.net Its installation in OpenBSD is not very complicated to set up. You will need to create a table in pf that will contain all the blacklisted IPs. Thus, we add in the /etc/pf.conf file a new table containing the IPs of the attackers who are immediately blocked: ``` table <sshguard> persist block in from <sshguard> ``` Reload the firewall with "# pfctl -f /etc/pf.conf". Now, we install sshguard as we usually do: ``` # pkg_add sshguard ``` Copy the configuration file given as an example: ``` # cp /usr/local/share/examples/sshguard/sshguard.conf.sample /etc/sshguard.conf ``` Edit this file if you want to make it more or less harsh. The default options are quite reasonable. We can now enable and run sshguard: ``` # rcctl enable sshguard # rcctl start sshguard ``` And there you go, your server is now safer. You may want to whitelist some IP addresses. Edit /etc/sshguard.friends and write, one per line, IP or ranges to ignore: ``` 46.23.93.119 192.168.1.0/24 10.0.0.1 ``` #### iblock : trap scanners solene@ wrote a tool named iblock. (HTM) https://tildegit.org/solene/iblock iblock ban every IP trying to access your server on ports that are actually unused. This is definitely a must-have. ## SSH: remote access to your server ### Configuring SSH SSH is a great tool π. You can access to your server from another computer. You can then manage it remotely without having to connect a keyboard and screen. Truth be told, with some exceptions, all servers are managed this way, but you are at home after all, so you can do whatever you want. SSH is a protocol useful for much more: encrypted tunnels, SFTP file storage space... Anyway, if you didn't enable SSH when installing OpenBSD, you can enable it with the following command: ``` # rcctl enable sshd ``` Although this protocol is reliable, it does not cost anything to take some safety precautions. We will edit the SSH configuration in the /etc/ssh/sshd_config file. * You can change the port used by default, for example: Port 222. In any case, remember to open this port in the firewall and redirect it to the router. It is not necessarily essential. * Very important, remove root's ability to connect in SSH with this line, in order to avoid bruteforce attacks directly on the "root" username: ``` PermitRootLogin no ``` To connect to the machine, you will need to create a normal user with the adduser command. Once the changes have been made, restart the SSH daemon: ``` # rcctl reload sshd ``` Later, to connect to the server, you will use the following command from your computer (in a terminal, or with a client like putty under windows): ``` $ ssh toto@chezmoi.tld ``` And if you changed the default port: ``` $ ssh -p 222 toto@chezmoi.tld ``` It will ask for the password of the user toto, then you can administer the server remotely. ### Log in with keys (without password) It is quite possible to connect with SSH without using a password. Instead, we use a pair of keys. This is a good idea at least for the following reasons: * It is much more secure. * It avoids writing a password every time π. * This is useful to run ssh commands in scripts. However, this requires you to have the private key on the device used to connect, which is not always the case. Here's how to proceed : On the server, edit the /etc/ssh/sshd_config file so it contains this line: ``` PubkeyAuthentication yes ``` Now, on the computer that is used to access the server, we will generate a key pair with the following command: ``` ssh-keygen -t ed25519 -f ~/.ssh/sshkey -a 100 ``` You will find two new files: * ~/.ssh/sshkey: this is your private key, **NEVER** share it with anyone. * ~/.ssh/sshkey.pub: the public key. Contrary to its name, it is like a lock that only the private key can fit. The ed25519 algorithm is suggested because it is very reliable at the moment. Do not enter a password and then wait for the keys to be generated. On an OpenBSD or Linux system, you will take care to edit your user's ~/.ssh/config file to fill it out as follows: ``` Host your_server HostName verylong.reallylong.too.long User myusername Port 222 PasswordAuthentication no IdentityFile ~/.ssh/sshkey ``` Of course, you will change the domain name of your server as well as the name of the user who must connect. Then run the following command to copy the public key to the server. ``` ssh-copy-id -p xxx -i ~/.ssh/sshkey.pub "myusername@verylong.reallylong.too.long" ``` Here, replace "xxx" with the port used by SSH if it's not 22. If the ssh-copy-id tool is not available, you must copy the public key manually. To display it, enter: ``` $ cat ~/.ssh/sshkey.pub ``` Connect to the server in SSH, then add in the file ~/.ssh/authorized_keys the contents of the file displayed previously. Once this is done, you can log in without having to enter a password with just the command: ``` $ ssh your_server ``` Convenient, isn't it? If that works as expected, you can disable password identification for good so that only the keyset is left as possibilities. Edit the /etc/ssh/sshd_config file to contain this line: ``` PasswordAuthentication no ``` β BE CAREFUL not to lose your set of keys! ### Upload a file on your server You may need to upload files to your server from time to time. Once SSH is configured, you will be able to use the scp command from any computer to copy a file to your server. For example : ``` $ scp -P <ssh port> user@athome.tld:/location/from/destination file-to-copy ``` It's very useful. However, if you want to transfer many files, backup or store documents, consider SFTP instead, which has more features such as resuming a partial transfer. If the files are too large, you can split them for multiple transfers. ### SSHFP DNS records The first time you connect to your server using SSH, the client gets the fingerprint of the server. Next time, it compares the previous checkprint and display a warning if it has changed because there might be a problem if you didn't touch your server since. It's called Trust On First Use (TOFU -- not the food , sorry). To avoid TOFU, you can publish data necessary to check the fingerprint the first time. To do so, we use a DNS SSHFP record. Enter "ssh-keygen -r athome.tld" and copy the result in your DNS zone. Don't forget to adjust the entries with a final dot "." after domain name or replace it with a "@" if necessary. As example : ``` @ IN SSHFP 1 1 97f5a9479fd16fbee1381c425297f7b2773a67a4 @ IN SSHFP 1 2 bd50a3c271e83dc769ea7c249a5c07aea1a817c62910129de56eba2763f93607 @ IN SSHFP 2 1 05fb8516842fc270ea5abda38d1c32b41e75da8a @ IN SSHFP 2 2 491489437e137d7d27959a4de3ba7660185ef98cbd3abc2287c82f82e8f032ab @ IN SSHFP 3 1 b7305417b0e981c4513642020a1f57ee03915af5 @ IN SSHFP 3 2 f15d33852df5f4043c77b6bf1c6134a5e11de0a513c1ec127fcbb8fae733b178 @ IN SSHFP 4 1 a1120fe90e69c0f534fece3dc837db6a262c3371 @ IN SSHFP 4 2 a36e418b517d95a74f1e0be1228d46e7aeaa8ed310359e91162d8c40b373eb55 ``` In order the client check these records with the server fingerprint at first connection, add option "VerifyHostKeyDNS" to ssh. In ~/.ssh/config : ``` Host * VerifyHostKeyDNS yes ``` Read more about this on SolΓ¨ne Rapenne's website: (HTM) https://dataswamp.org/~solene/2023-08-05-sshfp-dns-entries.html ## Keep the system up to date To ensure your system security, it is essential to keep it up to date. In order to apply the security patches, you must update: * The base system * Ports of third-party programs that you may have installed if a newer version is available. Short π: ``` # syspatch # pkg_add -u ``` ### Update ports (packages) Updating packages is as easy as : ``` # pkg_add -u ``` Yes that's all. π Thanks to solene who made this possible. (HTM) https://marc.info/?lu003dopenbsd-announce&mu003d156577865917831&wu003d2 Since this paragraph is a bit short, I take this opportunity to write two tips π. I suggest to add to /etc/daily.local the following line: ``` pkg_add -nu ``` This way, in the daily mail from Charlie Root, you will see what might happen if upgrades for packages are availables. Nothing is done for real, because if an updated program needs to be restarted, it may not work until it is. Thus, you are just warned of any updates to apply, and with the -n flag, the packages are kept in the cache in order to save time without risking to put a service down if it has to be restarted after the update. You will enter "# pkg_add -u" when you get the chance later. If you still want to apply the updates automatically, I advise you to first install the "checkrestart" port which will tell you if a service must be restarted after the update. This will therefore look like this in /etc/daily.local: ``` pkg_add -u echo "Service to restart with rcctl restart:" checkrestart ``` You will still have to reload the services manually with rcctl. ### Update the system First of all, a little reminder: OpenBSD is available in 3 "flavors": * release: this is the released version that you probably downloaded to install OpenBSD. * stable: this is the release version with several security fixes. This is what we would like to follow. * current: this is the next version in preparation of OpenBSD, in the CVS repository (which is used for source code development). It can indeed happen that bugs are discovered. Each time, fixes are quickly proposed. It is then recommended to apply the security patches. Since version 6.1, this operation is very simple with the following command: ``` # syspatch ``` The binary patches are then downloaded and installed. That's it! π It looked like this in OpenBSD 6.1 (a long time ago): ``` Get/Verify syspatch61-002_vmmfpu.tgz 100% | ******************************* | 9377 KB 00:49 Installing patch 002_vmmfpu Get/Verify syspatch61-003_libress ... 100% | ******************************* | 11391 KB 00:22 Installing patch 003_libressl ... ``` This tool is only available for i386, amd64, and more recently arm64 architectures. One may want to use the old method of source recovery and manual installation described in the official FAQ (for reasons). (HTM) https://www.openbsd.org/stable.html ### Be notified of updates To find out if updates need to be applied, you can consult the errata page which contains the list of available security patches. It is located at https://www.openbsd.org/errataXX.html where "XX" is the version number of your release, i.e "70" for OpenBSD 7.0. You can also be notified by email (and that's great π) of important updates available. Subscribe to the "announce" and "security-announce" lists. Send a first email to majordomo@OpenBSD.org simply containing: ``` subscribe announce ``` Then send a second message with: ``` subscribe security-announce ``` I also advise you to subscribe to the list indicating that there is a new version of ports by subscribing to the ports-security list: ``` subscribe ports-security ``` ### Upgrade from a version to another When a new major version of OpenBSD is available, the update procedure is always detailed on the official website. You must read the release notes when upgrading at "https://www.openbsd.org/faq/upgradeXX.html" where "XX" must be replaced by the version number you want to upgrade to. Since version 6.5, it only takes a simple command to update to the latest publication release: ``` # sysupgrade ``` ALWAYS check upgrade notes anyway π. ### Clean up after multiple updates If your installation is a bit outdated, you can check which files you may have forgotten to delete with the help of the sysclean port. The files which are not supposed to be present in a base system will then be listed. Read the output carefully, most of them are configuration files you created and want to keep π. ## Backup One can use its server to store important files. In any case, you also must think to backup the server itself. You never know when the hard drive will crash, when a storm will generate a power overload or when your cat will rush trought the wires πΌ. ### Automatic backup of / By default, you can backup / daily with OpenBSD See The official FAQ about /altroot (HTM) https://www.openbsd.org/faq/faq14.html#altroot It is relevant if you backup on a separate disk. If one day the main hard drive has a failure, you can boot on the /altroot. When you see the prompt boot>: Find the /altroot partition ``` boot> machine diskinfo ``` Then boot on the appropriate slice : ``` boot> boot -s hd1a:/bsd ``` β WARNING : only / is saved, with /etc. If you need to backup /var or /usr/local or else, you must plan this. Read the next part to do so π. Read also the official FAQ to duplicate filesystems. (HTM) https://www.openbsd.org/faq/faq14.html#DupFS ### Backup with rsync You may dedicate a partition to your backup, wether it's an external drive or an extra slice. Below, we use as example the mount point /mnt/bckp created for our needs. We will use the rsync tool. You can install it throught ports, but take note there is openrsync already available in base install. It is a less powerful rewrite of rsync but at least present in base. If the target device doesn't have rsync installed, add the option --rsync-path=openrsync. The rsync protocol will detect modified or new files to copy and don't bother with the others. As example, you can add those lines in /etc/weekly.local file weekly to backup /var and /usr/local: ``` /usr/local/bin/rsync -a --delete /var/ /mnt/bckp/var.bak/ /usr/local/bin/rsync -a --delete /usr/local/ /mnt/bckp/usrlocal.bak/ ``` This is a local backup, but you can use rsync though a SSH tunnel to send data from one computer to your server: ``` $ rsync -e "ssh" -avz --delete /directory/to/backup \ brucewayne@athome.tld:/mnt/bckp ``` ### Backup with tar tar let you create archives of a whole directory structure, and is available in base of course. Below is a suggestion to create a daily archive named with the current date. * BACKDIR is the backup mountpoint. If it is encrypted, add a call to "bioctl -p" accordingly in the script. * Every directory in "BACKLIST" is archived. ``` BACKDIR="/mnt/bckp" BACKLIST="/var /home /etc" for i in $BACKLIST; do backupfile="${BACKDIR}/$(basename ${i})-$(date +%F).tar.gz" tar -czf "${backupfile}" "${i}" done chmod 700 "${BACKDIR}" # remove olds #find "${BACKDIR}" -type f -mtime +90 -delete ``` Uncomment the last line to delete achives older than 90 days. ## SFTP : Secure file transfer One can see SFTP like FTP over SSH. Of course, it's a bit more than that π. It can continue partial transfer as example. If you have an SSH access to your server, you can sftp π. If you want to provide an SFTP server for multiple users, using a chroot might be helpful to keep everyone's data safe from others. We'll talk about it later. ### sftp usage To copy files with the user account "batman", start a new sftp session : ``` $ sftp batman@athome.tld ``` If you configured key authentication (good idea!), use -i flag : ``` $ sftp -i ~/.ssh/sshkey batman@athome.tld ``` Now you're in front of a prompt. You can enter commands such as : * put file : send a file to the server * get file : download a file from the server * ls : list files on the server * lls : list local files And also cd, mkdir, quit and help to get a list of availables commands. One can prefer to use a graphical tool to deal with sftp. Look at WinSCP for SFTP clients. Also, most file manager can handle sftp protocol. Try to open a path like: ``` sftp://batman@athome.tld:<port_number> ``` At least Gnome, KDE and XFCE default file browsers can do this. However, if your file manager don't support SFTP, you still can use sshfs (port "sshfs-fuse") to mount a remote SFTP location as any other mountpoints. ``` $ sshfs -d batman@athome.tld:/remote/dir /home/batman/sftp \ -o IdentityFile=/home/batman/.ssh/sshkey ``` ### chrooted SFTP If users share a storage space, you might want to lock them is a specific directory. Doing so, they can't reach other files above their own dedicated directory. It is interesting to keep everyone's data out of sight of the others, but also avoir sftp users to reach system files. This is called "chroot". In other words, if an user is chrooted in /var/sftp/batman, he can't read /var/sftp nor /var and even less /. For this user, /var/sftp/batman is the new root /. For the example, we'll chroot every sftp users in /var/sftp/user_name. You'll need to make the appropriates directories and carefully set permissions. They will all belong to a group named "sftpusers" in order to automatically chroot them when they sftp. Create this group : ``` # groupadd sftpusers ``` Then, edit /etc/ssh/sshd_config to chroot every user belonging to group sftpusers in /var/sftp ``` Match Group sftpusers ChrootDirectory /var/sftp/ ForceCommand internal-sftp AllowTcpForwarding no ``` Note you can do the same for a specific user: you just use a section Match User instead. If you wish users to authenticate using keys, then add to the above section : ``` PasswordAuthentication no ``` Reload ssh with "# rcctl reload sshd". Now make appropriate directories with required permissions for the chroot (this is critical): ``` # mkdir -p /var/sftp # chown root:wheel /var/sftp # chmod 700 /var/sftp ``` Read the next part to see how to create sftp users and their own directories. ### Add chrooted sftp users Any regular account belonging to sftpusers group will match the above rule. You might consider to restrict even more the access to sftp users : * Set the shell nologin to force sftp only sessions and disable other shells: "# useradd -G sftpusers -s /sbin/nologin -m new_user" * Change the password: "# passwd new_user" * Create the directory for the new user. He must be the only one with permissions to read it. Instead of using mkdir then chmod, you can do it with install : ``` # install -d -o new_user -g new_user -m 700 "/var/sftp/home/new_user" ``` Now, new_user is chrooted in /var/sftp/home/new_user when he logs in using sftp. Below find a script to ease this task: ``` ` #!/bin/sh # addsftpuser.sh : if [ $# -ne 1 ]; then Happy helping β here: You tried to output a spurious TAB character. This will break gopher. Please review your scripts. Have a nice day! Happy helping β here: You tried to output a spurious TAB character. This will break gopher. Please review your scripts. Have a nice day! fi # CHANGE ME CHROOT=/var/sftp/ user="$1" mkdir -p "${CHROOT}" useradd -G sftpusers -s /sbin/nologin -m "${user}" || exit 1 install -d -o ${user} -g ${user} -m 700 "${CHROOT}/home/${user}" exit ``` If you enable key authentication, then you'll have to fill /home/user/.ssh/authorized_keys with user's ssh public key. β I'm reffering to the file /home/user/.ssh/authorized_keys, NOT /var/sftp/home/user/.ssh/authorized_keys. --- (DIR) Table of contents (BIN) Donate --- (DIR) /