Si vous souhaitez me remonter des informations, ne pas hésiter
Transfer.sh permet de partager des fichiers via la commande sous windows (Invoke-RestMethod) et linux (curl) et bien d'autres (wget, http). Il est possible d'utiliser le service en ligne, ou de mettre en place un serveur au sein de votre infrastructure en local ou en ligne.
L'intérêt de le mettre en place dans votre entreprise ou sur un serveur dédié permet d'éviter le partage des fichiers sensibles sur un site externe
Voici le site de partage en question :
https://transfer.sh/
Vous avez deux possibilités
je vais détailler les deux possibilités en commençant par l'utilisation directement avec GO, puis dans la continuité, comment le compiler afin qu'il fonctionne sans prérequis sur tous les serveurs ayant la même architecture que le serveur qui la compilait
Nous allons utiliser une debian 10 et les outils seront en armv6 (GO ainsi que le programme compilé)
Si vous n'utilisez pas une architecture Arm sur votre serveur, il faudra donc choisir les outils adaptés au processeur utilisé
Les commandes seront identiques même si les architectures sont différentes (processeurs)
Commencez par installer debian 10
Mettez-le à jour
apt update && apt upgrade
&& sert à exécuter la commande suivante, si la première s'est bien déroulée
Voici les paquets prérequis depuis une debian sous LXC
apt install curl nano git unzip gcc
Allez sur le site de GO
Dans la liste un peu plus bas, télécharger la version qui correspond à votre architecture
Attention, n'installez pas le paquet GO présent dans la distribution (si vous avez les sources d'APT par défaut), car il est obsolète et ne fonctionne pas avec le script de mise en place de transfersh.
Dans mon cas je prends le paquet suivant : go1.16.3.linux-armv6l.tar.gz, cliquez sur le lien du paquet souhaité puis copiez le lien présent dans this link en haut de la page apparue
Allez sur votre serveur et entrez la commande suivante :
curl -SLO https://golang.org/dl/go1.16.3.linux-armv6l.tar.gz
Voici l'explication des options CURL
Entrez la commande suivante pour extraire l'archive dans le dossier des applications
tar -C /usr/local -xzf go1.16.3.linux-armv6l.tar.gz
Vous allez ajouter l'exécutable dans les variables d'environnement du système, ça permettra de faire appel à la commande go
Entrez la commande suivante pour faire les modifications au niveau de /etc/profile (Attention sur Ubuntu la modification se fait dans /etc/environment, faite le à la main car il n'y a qu'une ligne)
sed -i "$(grep -num2 PATH /etc/profile |cut -d':' -f1 | sed -z "s+\n+,+")s+PATH=\"+PATH=\"/usr/local/go/bin:+" /etc/profile
Explication de la commande:
commençons par $(grep -num2 PATH /etc/profile |cut -d':' -f1 | sed -z "s+\n+,+")
Cette commande va donc remplacer les 2 premières occurrences PATH=" par PATH="/usr/local/go/bin:. Si vous avez peur de vous tromper, faites les modifications à la main.
Une fois les modifications effectuées, redémarrer votre OS si vous avez modifié /etc/profile
reboot
Pour que la commande go ne soit appliquée qu'à un profil. Entrez la commande suivante
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
Il faudra fermer et réouvrir votre session pour que cela prenne effet.
Après le redémarrage ou la réouverture de session, vérifier si cela fonctionne correctement
go version
Vous devriez avoir la version actuelle de GO
Il y à deux façons de faire
Manuel
Allez sur le git de transfertsh pour télécharger l'archive
Cliquez sur l'icône vert (code), faite un clic droite sur download zip et copier l'URL
Sur votre serveur, tapez la commande copiée
curl -SLO https://github.com/dutchcoders/transfer.sh/archive/refs/heads/master.zip
Automatique
git clone https://github.com/dutchcoders/transfer.sh.git
dézipper l'archive
unzip master.zip
Puis entrez dans le dossier dézippé
cd transfer.sh-master/
Trouvez l'IP de la machine si vous ne l'avez pas déjà avec la commande
ip a
Testez le fonctionnement en root. La première fois ça peut prendre un certain temps, car il va télécharger tous les prérequis et compiler le programme
go run main.go --provider=local --listener :8080 --basedir=/tmp/
Explication de la commande
Une fois la compilation terminée vous aurez le message suivant : listening on port: :8080
Allez sur le navigateur de votre poste de travail et entrez l'adresse du serveur
IP:8080
Si la page de transfersh apparait, alors c'est que cela fonctionne.
Retournez sur le serveur et faites CTRL + C de votre clavier pour quitter le programme
Depuis le dossier dans lequel vous avez lancé le programme, entrez la commande suivante
go build -o transfersh main.go
Dès que vous reprenez la main sur le terminal, lancez la commande suivante pour tester le programme
./transfersh --provider=local --listener :8080 --basedir=/tmp/
Dès que le message suivant apparait listening on port: :8080, connectez-vous à IP:8080 avec un navigateur
Si tout fonctionne, retournez au terminal du serveur et faites un CTRL+C pour quitter le programme
Vous pouvez copier transfersh sur un autre serveur qui à une architecture identique au serveur sur lequel vous l'avez compilé pour la mise en production.
Pour avoir toutes les options disponibles, il suffit de faire un ./transfersh --help
en étant dans le dossier de l'application
Comme vous l'avez remarqué il y a beaucoup de possibilités, concentrons-nous sur les plus élémentaires
--purge-days value Nombre de jours de rétention des fichiers
--purge-interval value Nombre d'heures de rétention des fichiers
--max-upload-size value Taille maximum des fichiers envoyés (en kilooctet)
--log value Chemin du fichier log
--http-auth-user value Nom d'utilisateur pour la demande d'authentification
--http-auth-pass value Mot de passe pour la demande d'authentification
--ip-whitelist value Liste des ip autorisés a se connecter séparer avec des virgule (,)
--ip-blacklist value Liste des ip non autorisés à se connecter séparer avec des virgule (,)
Attention ci-dessous, vous devez choisir soit l'utilisation de certificats autosignés pour un accès local en général, soit la mise en place de certificats fournis par lets encrypt dans le cas d'un accès depuis l'extérieur (serveur dédié).
Pour lancer le serveur en HTTPS, il faudra générer un certificat autosigné avec les commandes suivantes
mkdir /etc/ssl/transfersh/
openssl genrsa -out /etc/ssl/transfersh/transfersh.key 2048
openssl req -new -key /etc/ssl/transfersh/transfersh.key -out /etc/ssl/transfersh/transfersh.csr
openssl x509 -req -days 365 -in /etc/ssl/transfersh/transfersh.csr -signkey /etc/ssl/transfersh/transfersh.key -out /etc/ssl/transfersh/transfersh.crt
./transfersh --provider=local --basedir=/tmp/ --tls-listener-only --tls-listener 0.0.0.0:443 --tls-private-key /etc/ssl/transfersh/transfersh.key --tls-cert-file /etc/ssl/transfersh/transfersh.crt
Ou avec Go
go run main.go --provider=local --basedir=/tmp/ --tls-listener-only --tls-listener 0.0.0.0:443 --tls-private-key /etc/ssl/transfersh/transfersh.key --tls-cert-file /etc/ssl/transfersh/transfersh.crt
Commencez par installer certbot
apt install certbot
Faites votre enregistrement DNS vers le serveur ou vous utiliserez transfersh
Entrez la commande suivante
certbot certonly --standalone --agree-tos -d SOUSDOMAINE.VOTREDOMAINE --register-unsafely-without-email
Voici l'explication de la commande
SOUSDOMAINE.VOTREDOMAINE remplacer cela par votre domaine ou sous domaine
Puis exécuter transfersh
./transfersh --provider=local --basedir=/tmp/ --tls-listener-only --tls-listener 0.0.0.0:443 --tls-private-key /etc/letsencrypt/live/SOUSDOMAINE.VOTREDOMAINE/privkey.pem --tls-cert-file /etc/letsencrypt/live/SOUSDOMAINE.VOTREDOMAINE/fullchain.pem
Ou avec Go
go run main.go --provider=local --basedir=/tmp/ --tls-listener-only --tls-listener 0.0.0.0:443 --tls-private-key /etc/letsencrypt/live/SOUSDOMAINE.VOTREDOMAINE/privkey.pem --tls-cert-file /etc/letsencrypt/live/SOUSDOMAINE.VOTREDOMAINE/fullchain.pem
Vous voilà avec transfertsh en mode HTTPS avec des certificats fournis par lets encrypt
Le renouvèlement des certificats est automatique, il se fait via un cron qui est dans /etc/cron.d/certbot qui s'exécute tout les 12h
Je vais vous expliquer comment le mettre en production, nous allons voir les éléments suivants
Pour ceux qui feraient une mise en production à l'extérieur, je recommande une sécurisation plus stricte via GEOIP et fail2ban et d'utiliser les options du logiciel --ip-whitelist et --ip-blacklist
Geoip pour restreindre l'accès à certains pays
Fail2ban pour bannir les erreurs 404 liées à la recherche d'URL par brute force. Mais aussi avec portsentry pour bannir les scans de port du serveur
Copiez l'exécutable dans le dossier /usr/local/bin/
du serveur de production
cp transfersh /usr/local/bin/
/usr/local/bin est le répertoire dédié aux applications qui ne sont pas liées au système
Avant de créer le service, vous allez créer un utilisateur qui servira au lancement du service, le but étant de donner un minimum de droits pour éviter les risques de compromettre le serveur
Entrez la commande suivante
adduser --system --no-create-home --shell /bin/bash --disabled-password --disabled-login transfersh
Créer le fichier log pour le service
touch /var/log/transfersh.log
Vous modifiez les droits du fichier pour que l'utilisateur transfersh puisse écrire dedans
chown transfersh /var/log/transfersh.log
Maintenant, vous allez créer le service systemd
nano /etc/systemd/system/transfersh.service
[Unit]
Description=Transfersh permet l'envoi de fichiers en ligne de commande
After=network-online.target
[Service]
Type=simple
User=transfersh
UMask=077
ExecStart=/usr/local/bin/transfersh --provider=local --basedir=/tmp/ --tls-listener-only --tls-listener 0.0.0.0:443 --tls-private-key /etc/ssl/transfersh/privkey1.pem --tls-cert-file /etc/ssl/transfersh/fullchain1.pem --purge-days 6 --max-upload-size 1000000 --log /var/log/transfersh.log
Restart=on-failure
# Configures the time to wait before service is stopped forcefully.
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target
After=network-online.target démarre après le service indiqué, dans notre cas après le lancement de l'interface ethernet
UMask=077 Indique le masque des fichiers créés, ça sera 700 car on indique le masque d'annulation, donc 777 - 077 = 700
ExecStart= La commande à exécuter
Restart=on-failure redémarre en ça d'échec du lancement
TimeoutStopSec=300 temps avant arrêt forcé du service (cas de l'arrêt du serveur par exemple)
WantedBy=multi-user.target fonctionne que lors du démarrage du système en mode multiuser
Nous allons déplacer les certificats lets encrypt pour permettre à l'utilisateur transfersh d'y accéder
cp /etc/letsencrypt/archive/dependancenum.fr/{fullchain1.pem,privkey1.pem} /etc/ssl/transfersh/
Puis nous modifions les droits de l'utilisateur pour que transfersh puisse accéder aux clés
chown -R transfersh /etc/ssl/transfersh
Vous allez attribuer les droits d'écriture et lecture et d'exécution au dossier transfersh
chmod 700 /etc/ssl/transfersh/
Nous donnons les droits minimums à la clé privés
chmod 400 /etc/ssl/transfersh/privkey1.pem
Ajouter la ligne suivante dans /etc/cron.d/certbot, cette ligne va vérifier le checksum des certificats public (celui de lets encrypt et celui copié), et s'il y a une différence, c'est que le certificat a changé. Ainsi il copie les nouveaux et modifier les droits utilisateurs sur les certificats copiés
5 */12 * * * root if [ $(md5sum /etc/letsencrypt/archive/dependancenum.fr/fullchain1.pem|awk -F " " '{print $1}') = $(md5sum /etc/ssl/transfersh/fullchain1.pem|awk -F " " '{print $1}') ]; then echo "certificats vérifié et à jour" >> /var/log/transfersh.log; else systemctl stop transfersh && cp -f /etc/letsencrypt/archive/dependancenum.fr/{fullchain1.pem,privkey1.pem} /etc/ssl/transfersh/ && chown -R transfersh /etc/ssl/transfersh && chmod 400 /etc/ssl/transfersh/{fullchain1.pem,privkey1.pem} && systemctl start transfersh && echo "certificat remplacé" >> /var/log/transfersh.log; fi
[Unit]
Description=Transfersh permet l'envoi de fichiers en ligne de commande
After=network-online.target
[Service]
Type=simple
User=transfersh
UMask=077
ExecStart=/usr/local/bin/transfersh --provider=local --basedir=/tmp/ --listener 0.0.0.0:80 --purge-days 6 --max-upload-size 1000000 --log /var/log/transfersh.log
OU
ExecStart=/usr/local/bin/transfersh --provider=local --basedir=/tmp/ --tls-listener-only --tls-listener 0.0.0.0:443 --tls-private-key /etc/ssl/transfersh/transfersh.key --tls-cert-file /etc/ssl/transfersh/transfersh.crt
Restart=on-failure
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target
chown -R transfersh:root /etc/ssl/transfersh/
chmod 700 /etc/ssl/transfersh/
chmod 400 /etc/ssl/transfersh/transfersh.key
Pour automatiser le renouvellement du certificat, nous allons vérifier la validité de celui-ci, si il n'est plus valide alors il crée un nouveau certificat
Ajouter cela à /etc/crontab
5 */12 * * * root if true | openssl s_client -connect 127.0.0.1:443 2>/dev/null | openssl x509 -noout -checkend 0; then echo "Certificat encore valide" >> /var/log/transfersh.log; else echo "Certificat expiré, actualisation du certificat le $(date '+%d/%m/%Y %r') pour 1 an" >> /var/log/transfersh.log && systemctl stop transfersh && rm /etc/ssl/transfersh/transfersh.crt && openssl x509 -req -days 365 -in /etc/ssl/transfersh/transfersh.csr -signkey /etc/ssl/transfersh/transfersh.key -out /etc/ssl/transfersh/transfersh.crt && systemctl start transfersh; fi
Comme vous allez lancer votre service avec un utilisateur système sur le port 443 ou 80. Il va falloir l'autoriser à écouter sur l'un de ces ports
Seul root a le droit d'écouter sur les ports jusqu'à 1024, il va donc falloir modifier les capabilities sur votre exécutable pour que l'utilisateur transfersh ait le droit d'écoute sans être root. C'est une alternative à setuid. Au lieu de donner les droits root de façon générale, il les donne sur une partie des accès à UN programme. Dans notre cas l'ouverture de ports inférieur à 1024 qui nécessite les droits root
Vous allez donner les droits à l'application transfersh uniquement sur la partie ouverture de port, cela à tous les utilisateurs (cela peut être appliqué à un utilisateur si besoin)
setcap cap_net_bind_service=pe `which transfersh`
On affiche les droits capabilities appliqués à transfersh, vous devriez avoir la ligne suivante : /usr/local/bin/transfersh = cap_net_bind_service+ep
getcap `which transfersh`
Activez le service
systemctl enable transfersh
On lance le service
systemctl start transfersh
Sous Windows voici la commande à entrer
Attention pour utiliser l'option -SkipCertificateCheck
il faut avoir la version 6.0.0 de Powershell minimum, car elle a été implémentée que depuis cette version comme l'indique microsoft
Pour connaitre la version de Powershell que vous avez, ouvrez Powershell et entrer la commande suivante
$PsVersionTable
Allez sur ce lien pour mettre à jour votre version de Powershell, télécharger la version stable powershell
Dans le cas d'un certificat autosigné, entrez la commande suivante pour uploader votre fichier
Invoke-RestMethod -SkipCertificateCheck -Method PUT -InFile .\fichier -Uri https://IPSRV/fichier
Si vous avez mis en place un certificat lets encrypt, Vous utiliserez la commande suivante
Invoke-RestMethod -Method PUT -InFile .\fichier -Uri https://IPSRV/fichier
Sous Linux voici la commande avec un certificat délivré par lets encrypt
curl --upload-file ./hello.txt https://IPSRV/hello.txt
Sous Linux voici la commande avec un certificat autosigné
curl -k --upload-file ./hello.txt https://IPSRV/hello.txt
Les autres options sont disponibles sur le Github
https://gist.github.com/r4dian/47c60f43fcfc68059cbe
https://github.com/dutchcoders/transfer.sh
https://www.digitalocean.com/community/tutorials/how-to-install-go-on-debian-10
https://golang.org/doc/install?download=go1.16.3.linux-armv6l.tar.gz
https://transfer.sh/
https://connect.ed-diamond.com/GNU-Linux-Magazine/GLMF-164/Les-capabilities-sous-Linux
https://sametmax.com/ecouter-sur-le-port-80-sans-etre-root/
https://doc.ubuntu-fr.org/creer_un_service_avec_systemd
https://ubuntuplace.info/questions/389535/how-do-you-add-cap-sys-admin-permissions-to-user-in-centos-7
https://pelicanux.net/blog/2018/07/19/durcissement-systeme-avec-les-capabilities-linux/
https://stackoverflow.com/questions/1956732/is-it-possible-to-configure-linux-capabilities-per-user
https://doc.ubuntu-fr.org/acl
https://ubuntuplace.info/questions/313612/script-to-check-if-ssl-certificate-is-valid
https://github.com/PowerShell/PowerShell
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7.1
https://unix.stackexchange.com/questions/60750/does-curl-have-a-no-check-certificate-option-like-wget