$_ BSDHowTo.ch
How To... Why not..? Scripts RSS logo

How to publish your web pages using SFTP

Last update: 2018-08-29

Introduction

In this post I show you how to leverage SFTP for publishing your web pages. All you need for this is OpenSSH and a dedicated user with a keypair for authentication. Of course I have tested the commands I show you in this post on OpenBSD.

Create the dedicated user

I want to restrict the new user as much as possible. Use the following command to create the account:

$ doas useradd webpub
doas (user@fqdn.example.com) password:
useradd: Warning: home directory `/home/publish' doesn't exist, and -m was not specified

I’ve left away the parameter -m because I don’t want useradd(8) to create /home/webpub and populate it with the contents of /etc/skel. Up next you create the folder structure required for the new user:

$ doas mkdir -m 755 /home/webpub
$ doas mkdir -m 700 /home/webpub/.ssh
$ doas chown -R webpub:webpub /home/webpub

This user must only be used for transfering files to /var/www/htdocs/, so do not want to allow any other kind of login. Using vipw(8) I set the shell for the user to /sbin/nologin:

$ doas vipw
:/^webpub/s/\/bin\/ksh/\/sbin\/nologin/
:wq

Create the public/private key pair

The user can only use a keypair to login into SSH as the account doesn’t have a password. With this commands you create valid keypair and install it:

$ doas -u webpub ssh-keygen -t ed25519
...
$ doas -u webpub mv /home/webpub/.ssh/ed25519.pub /home/publish/.ssh/authorized_keys
$ doas mv /home/webpub/.ssh/id_ed25519 ./id_webpub

Configure sshd(8)

In sshd_config(5) you can use Match blocks to change the behviour of sshd(8) depending on different variables. I add such a Match block to restrict the user webpub to /var/www/htdocs/ and prevent him from using any SSH functionality beside SFTP.

Match user webpub
	ChrootDirectory /var/www/htdocs
	DisableForwarding yes
	ForceCommand internal-sftp
	PasswordAuthentication no
	PermitTTY no
	PermitTunnel no

You must reload the configuration to let sshd(8) know about it:

$ doas rcctl reload sshd