From ec7aac25e99a6c9e59b5606a7f67f2a8a6565c20 Mon Sep 17 00:00:00 2001 From: Alex Garel Date: Wed, 29 Nov 2023 17:47:57 +0100 Subject: [PATCH] =?UTF-8?q?feat:=C2=A0new=20sftp=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- confs/proxy-off/sshd_config/sftp | 240 -------------------------- confs/proxy-off/sshd_config/sftp.conf | 17 ++ docs/nginx-reverse-proxy.md | 4 +- docs/producers_sftp.md | 28 ++- scripts/off1/add_sftp_user.pl | 86 --------- scripts/proxy-off/add_sftp_user.pl | 121 +++++++++++++ 6 files changed, 166 insertions(+), 330 deletions(-) delete mode 100644 confs/proxy-off/sshd_config/sftp create mode 100644 confs/proxy-off/sshd_config/sftp.conf delete mode 100755 scripts/off1/add_sftp_user.pl create mode 100755 scripts/proxy-off/add_sftp_user.pl diff --git a/confs/proxy-off/sshd_config/sftp b/confs/proxy-off/sshd_config/sftp deleted file mode 100644 index 7b548594..00000000 --- a/confs/proxy-off/sshd_config/sftp +++ /dev/null @@ -1,240 +0,0 @@ -# Configuration of sftp users -# -# sftp is used by producers or other data providers to submit data to integrate to openfoodfacts -# -# Example of overriding settings on a per-user basis -#Match User anoncvs -# X11Forwarding no -# AllowTcpForwarding no -# PermitTTY no -# ForceCommand cvs server - -Match User carrefour - ChrootDirectory /home/sftp/carrefour - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User systemeu - ChrootDirectory /home/sftp/systemeu - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User daniel - ChrootDirectory /home/sftp/daniel - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - - -Match User fleurymichon - ChrootDirectory /home/sftp/fleurymichon - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - - -Match User casino - ChrootDirectory /home/sftp/casino - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User composcan - ChrootDirectory /home/sftp/composcan - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User ldc - ChrootDirectory /home/sftp/ldc - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User monoprix - ChrootDirectory /home/sftp/monoprix - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User scamark - ChrootDirectory /home/sftp/scamark - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User auchan - ChrootDirectory /home/sftp/auchan - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User foodvisor - ChrootDirectory /home/sftp/foodvisor - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User saintelucie - ChrootDirectory /home/sftp/saintelucie - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User sodiaal - ChrootDirectory /home/sftp/sodiaal - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User nsgroup - ChrootDirectory /home/sftp/nsgroup - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User sodebo - ChrootDirectory /home/sftp/sodebo - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User ppenmarch - ChrootDirectory /home/sftp/ppenmarch - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User auroremarket - ChrootDirectory /home/sftp/auroremarket - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User bonduelle - ChrootDirectory /home/sftp/bonduelle - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User sebleouf - ChrootDirectory /home/sftp/sebleouf - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User bonduellebr - ChrootDirectory /home/sftp/bonduellebr - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User crepebroceliande - ChrootDirectory /home/sftp/crepebroceliande - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User dacobello - ChrootDirectory /home/sftp/dacobello - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User lutti - ChrootDirectory /home/sftp/lutti - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User lafel - ChrootDirectory /home/sftp/lafel - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User noracdobrasil - ChrootDirectory /home/sftp/noracdobrasil - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User naturalia - ChrootDirectory /home/sftp/naturalia - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User amelie - ChrootDirectory /home/sftp/amelie - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User artinformatique - ChrootDirectory /home/sftp/artinformatique - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User danone - ChrootDirectory /home/sftp/danone - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User unilever - ChrootDirectory /home/sftp/unilever - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User delhaize - ChrootDirectory /home/sftp/delhaize - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User loue - ChrootDirectory /home/sftp/loue - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User franprix - ChrootDirectory /home/sftp/franprix - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User equadis - ChrootDirectory /home/sftp/equadis - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User traceone - ChrootDirectory /home/sftp/traceone - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User elcoco - ChrootDirectory /home/sftp/elcoco - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User carrefourespana - ChrootDirectory /home/sftp/carrefourespana - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp - -Match User bayard - ChrootDirectory /home/sftp/bayard - X11Forwarding no - AllowTcpForwarding no - ForceCommand internal-sftp diff --git a/confs/proxy-off/sshd_config/sftp.conf b/confs/proxy-off/sshd_config/sftp.conf new file mode 100644 index 00000000..9964a63d --- /dev/null +++ b/confs/proxy-off/sshd_config/sftp.conf @@ -0,0 +1,17 @@ +# Configuration of sftp users +# +# sftp is used by producers or other data providers to submit data to integrate to openfoodfacts +# + +# sftp configuration, for all users of sftponly group +Match Group sftponly + # %u is local use id + # force user to stay in is directory + ChrootDirectory /mnt/off-pro/sftp/%u + # public keys are in sftp directory + AuthorizedKeysFile /mnt/off-pro/sftp/%u_authorized_keys + # some security parameters + X11Forwarding no + AllowTcpForwarding no + # only allow sftp + ForceCommand internal-sftp diff --git a/docs/nginx-reverse-proxy.md b/docs/nginx-reverse-proxy.md index c4cc8527..d4f47122 100644 --- a/docs/nginx-reverse-proxy.md +++ b/docs/nginx-reverse-proxy.md @@ -1,6 +1,8 @@ # NGINX Reverse proxy (OVH) -At OVH and at Free we have a LXC container dedicated to reverse proxy http/https applications. It serves applications that are located in servers at the same provider (and same Proxmox cluster). +At OVH and at Free we have a LXC container dedicated to reverse proxy http/https applications. + +It serves applications that are located in servers at the same provider (and same Proxmox cluster). ## Network specific interface diff --git a/docs/producers_sftp.md b/docs/producers_sftp.md index 47e07da4..cc948423 100644 --- a/docs/producers_sftp.md +++ b/docs/producers_sftp.md @@ -4,10 +4,32 @@ We have a producer SFTP which is part of the producer platform. This sftp is used by producers who send files for regular automated updates of their products. -The sftp is located on off1.openfoodfacts.org +The sftp is located on the reverse proxy container (because it needs it's own network interface). -The `/home/sftp` folder links to `/srv/sftp/` and contains home for sftp users. +The sftp directory is a ZFS dataset in `zfs-hdd/off-pro/sftp`. +It is mounted as `/mnt/off-pro/sftp`: +* in the reverse proxy to give access to producers themselves (through sftp) +* and in off-pro container to give access to files to the producers platform. + +In the reverse proxy container, the sftp is configured in /etc/ssh/sshd_config.d/sftp.conf which is a symlink to `confs/proxy-off/sshd_config/sftp.conf` in this repository. + +If a producer want's to connect with a key, put the public key in a file named `/mnt/off-pro/sftp/_authorized_keys`. ## Adding a new sftp user -Use the script [`add_sftp_user.pl`](../scripts/off1/add_sftp_user.pl) (present in `/home/script`) with user root. \ No newline at end of file +Use the script [`add_sftp_user.pl`](../scripts/off1/add_sftp_user.pl) (present in `script/off-proxy`) with user root in the reverse proxy container. + +**:fire: IMPORTANT :fire::** every user **must be in `sftponly` group** and only in this one. + +You may eventually communicate the server key fingerprint to the producer +(get it with `ssh-keyscan $(hostname) | ssh-keygen -lf -`) + +It's better to test access before sending the mail to the producer: + +```bash +lftp sftp://user@sftp.openfoodfacts.org +password: +> ls +``` + +(issue at least an `ls` because `lftp` only try to connect at the first command) diff --git a/scripts/off1/add_sftp_user.pl b/scripts/off1/add_sftp_user.pl deleted file mode 100755 index c2ae9230..00000000 --- a/scripts/off1/add_sftp_user.pl +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/perl -w - -use strict; - -use String::MkPasswd qw(mkpasswd); -use Crypt::PasswdMD5 qw(unix_md5_crypt); - - -my $user = $ARGV[0]; - -if (not defined $user) { - die("Need user name (only a to z letters, at least 3 letters)\n"); -} - -if ($user !~ /^[a-z]{3}([a-z]*)$/) { - die("Invalid user name: $user (only a to z letters, at least 3 letters.\n"); -} - -my $sftpdir = "/home/sftp"; - -if (-e "$sftpdir/$user") { - die("Directory $sftpdir/$user already exists.\n"); -} - -mkdir("$sftpdir/$user", 0755) or die("Could not create dir $sftpdir/$user : $!\n"); -mkdir("$sftpdir/$user/data", 0755) or die("Could not create dir $sftpdir/$user/data : $!\n"); - -my $password = mkpasswd(-minspecial=>0); - -my @salt = ( '.', '/', 0 .. 9, 'A' .. 'Z', 'a' .. 'z' ); - -sub gensalt { - my $count = shift; - my $salt; - for (1..$count) { - $salt .= (@salt)[rand @salt]; - } - return $salt; -} - -my $password_hash = unix_md5_crypt($password, gensalt(8)); - -system("useradd", "$user", "-d", "/home/sftp/$user/data", "-g", "1006", "-M", "-N", "-p", $password_hash); -system("chown", "-R", "$user:sftponly", "/home/sftp/$user/data"); - -open (my $OUT, ">>", "/etc/ssh/sshd_config"); -print $OUT < \$pubkey) or die("$usage\n"); + +my $user = $ARGV[0]; +if (not defined $user) { + die("$usage\nError: Need user name $user_help.\n"); +} + +if ($user !~ /^[a-z]{3}([a-z]*)$/) { + die("$usage\nError:Invalid user name: $user $user_help.\n"); +} + +print("This script was not really tested (yet), are you sure you want to do continue? (y/n)\n"); +my $confirm = ; +if ($confirm!~ /^y/i) { + die("Aborting.\n"); +} + + +if (-e "$sftpdir/$user") { + die("Directory $sftpdir/$user already exists.\n"); +} + +mkdir("$sftpdir/$user", 0755) or die("Could not create dir $sftpdir/$user : $!\n"); +mkdir("$sftpdir/$user/data", 0755) or die("Could not create dir $sftpdir/$user/data : $!\n"); + +my $password = mkpasswd(-minspecial=>0); + +my @salt = ( '.', '/', 0 .. 9, 'A' .. 'Z', 'a' .. 'z' ); + +sub gensalt { + my $count = shift; + my $salt; + for (1..$count) { + $salt .= (@salt)[rand @salt]; + } + return $salt; +} + +my $password_hash = unix_md5_crypt($password, gensalt(8)); + +my $user_dir = "$sftpdir/$user"; + +# we just need to create the user and add it to the sftp group +my @user_cmd = ("useradd", "$user", "-d", "$user_dir/data", "-g", "1006", "-M", "-N", "-p", $password_hash); +print("running: ". join(" ", @user_cmd) . "\n"); +system(@user_cmd); +my @chown_cmd = ("chown", "-R", "$user:sftponly", "$user_dir/data"); +print("running: " . join(" ", @chown_cmd) . "\n"); +system(@chown_cmd); + +# copy pub key if given, else just create the file +my $pub_key_file = "$sftpdir/${user}_authorized_keys"; +open(my $FILE, '>>', $pub_key_file) or print("Error Could not open $pub_key_file: $!\n"); +if (defined $FILE) { + print($FILE,"\n$pubkey\n"); + close($FILE); +} + +# note we don't need a ssh reload as the configuration is based on the group, +# see confs/proxy-off/sshd_config/sftp.conf +# my @ssh_reload_cmd = ("systemctl", "reload", "ssh"); +# print("running: " . join(" ", @ssh_reload_cmd) ."\n"); +# system(@ssh_reload_cmd); + +# get server keys to allow validation on first connection + +my @keys = `ssh-keyscan $hostname | ssh-keygen -lf -`; +@keys = grep {$_ !~ '^#'} @keys; +my $keys_txt = join("", @keys); + +# print mail content +print <