DISCLAIMER: these notes reflect my knowledge and understanding of subjects, not the ultimate truth. Corrections are welcome
📅 2024-10-01 📄 source
Hide your private NixOS server from hordes of crackers which scan IPs and probe for vulnerabilities, while retaining ability to access it yourself from any network
How this works:
Obviously gateways which carry traffic between your client and your server can see that your server exists and is protected like this, possibly drawing attention to it from even more powerful entities, but that's a matter of choice:)
fwknop is for FireWall Knock OPerator
fwknop package including both fwknopd server and fwknop client is in nixpkgs, but it's regular package which is installed into its Nix store path and isn't "integrated" into NixOS in any way. To make it run as systemd service with my config, I explicitly declare systemd service and config files in /etc in my configuration.nix:
systemd.services.fwknopd = {
description = "fwknopd Service";
after = [ "network.target" ];
serviceConfig.ExecStart = "${pkgs.fwknop}/bin/fwknopd --conf /etc/fwknop/fwknopd.conf --foreground";
wantedBy = [ "multi-user.target" ];
};
environment.etc."fwknop/fwknopd.conf".text = ''
PCAP_INTF eth0;
'';
environment.etc."fwknop/access.conf".text = ''
SOURCE ANY
OPEN_PORTS tcp/22
REQUIRE_SOURCE_ADDRESS Y
KEY_BASE64: Sz80RjpXOlhH2olGuKBUamHKcqyMBsS9BTgLaMugUsg=
HMAC_KEY_BASE64: c0TOaMJ2aVPdYTh4Aa25Dwxni7PrLo2zLAtBoVwSepkvH6nLcW45Cjb9zaEC2SQd03kaaV+Ckx3FhCh5ohNM5Q==
'';
These keys are from documentation example, don't bother trying to find my server:) Convenient fwknop client cmd to generate random keys: fwknop --key-gen
fwknop client command to send auth packet: fwknop --access tcp/22 --allow-ip ${CLIENT_IP} --destination ${SERVER_IP} --key-base64-rijndael ${KEY_BASE64} --key-base64-hmac ${HMAC_KEY_BASE64}
(or check docs to make it read keys from file so that they are not visible in process cmdline)
NixOS by default allows incoming ICMPv4 echo requests, to prevent this: networking.firewall.allowPing = false
NixOS by default opens ports for network services which you enable via its config, to prevent this for sshd: services.openssh.openFirewall = false
And just to have all in one place, to allow SSH access for just one user and only with key auth:
services.openssh.settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
AllowUsers = [ "user" ];
};
and add public key to ~user/.ssh/authorized_keys
Comments are not implemented, but you can create issue on GitHub or check existing ones
Return to index