Skip to content

Instantly share code, notes, and snippets.

@ghuntley
Last active May 6, 2023 16:27
Show Gist options
  • Save ghuntley/9369011a979ce2422d9851e38e784895 to your computer and use it in GitHub Desktop.
Save ghuntley/9369011a979ce2422d9851e38e784895 to your computer and use it in GitHub Desktop.
ghuntley-net
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, lib, pkgs, ... }:
{
imports =
[
./hardware-configuration.nix
];
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.device = "/dev/vda";
networking.hostName = "ghuntley-net";
time.timeZone = "UTC";
networking.useDHCP = false;
networking.interfaces.ens3.useDHCP = true;
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "us";
};
users.users.ghuntley = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" ]; # Enable ‘sudo’ for the user.
};
environment.systemPackages = with pkgs; [
nixpkgs-fmt
elinks
vim
htop
tmux
docker
restic
rclone
imagemagick
parted
mastodon
];
services.tailscale.enable = true;
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
services.openssh.enable = true;
services.openssh.passwordAuthentication = false;
services.openssh.permitRootLogin = "no";
programs.mosh.enable = true;
security.acme.email = "[email protected]";
security.acme.acceptTerms = true;
services.nginx = {
enable = true;
# Use recommended settings
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
# Only allow PFS-enabled ciphers with AES256
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
commonHttpConfig = ''
# Add HSTS header with preloading to HTTPS requests.
# Adding this header to HTTP requests is discouraged
map $scheme $hsts_header {
https "max-age=31536000; includeSubdomains; preload";
}
add_header Strict-Transport-Security $hsts_header;
# Enable CSP for your services.
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
# Minimize information leaked to other domains
add_header 'Referrer-Policy' 'origin-when-cross-origin';
# Disable embedding as a frame
add_header X-Frame-Options DENY;
# Prevent injection of code in other mime types (XSS Attacks)
add_header X-Content-Type-Options nosniff;
# Enable XSS protection of the browser.
# May be unnecessary when CSP is configured properly (see above)
add_header X-XSS-Protection "1; mode=block";
# This might create errors
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
'';
};
services.nginx.virtualHosts."ghuntley.net" = {
forceSSL = false;
enableACME = true;
root = "/srv/ghuntley.net";
};
services.nginx.virtualHosts."ghuntley.com" = {
forceSSL = true;
enableACME = true;
locations."/" = {
extraConfig = ''
proxy_pass http://localhost:3001;
proxy_pass_header Authorization;
proxy_http_version 1.1;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
'';
};
locations."/.well-known/webfinger" = {
extraConfig = ''
return 301 https://fediverse.ghuntley.com$request_uri;
'';
};
locations."/linktree/" = {
extraConfig = ''
alias /srv/ghuntley.com/static/linktree/;
'';
};
locations."/notes/" = {
extraConfig = ''
proxy_pass https://ghuntleynotes.netlify.app;
proxy_pass_header Authorization;
proxy_http_version 1.1;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
'';
};
};
services.nginx.virtualHosts."fediverse.ghuntley.com" = {
forceSSL = true;
enableACME = true;
root = "${config.services.mastodon.package}/public/";
locations."/system/".alias = "/var/lib/mastodon/public-system/";
locations."/" = {
tryFiles = "$uri @proxy";
};
locations."@proxy" = {
proxyPass = (if config.services.mastodon.enableUnixSocket then "http://unix:/run/mastodon-web/web.socket" else "http://127.0.0.1:${toString(config.services.mastodon.webPort)}");
proxyWebsockets = true;
};
locations."/api/v1/streaming/" = {
proxyPass = (if config.services.mastodon.enableUnixSocket then "http://unix:/run/mastodon-streaming/streaming.socket" else "http://127.0.0.1:${toString(config.services.mastodon.streamingPort)}/");
proxyWebsockets = true;
};
};
#
# https://docs.joinmastodon.org/admin/config/
#
services.elasticsearch.enable = true;
services.elasticsearch.package = pkgs.elasticsearch7;
services.mastodon.elasticsearch.host = "localhost";
services.mastodon.enable = true;
services.mastodon.enableUnixSocket = false;
services.mastodon.configureNginx = false;
services.mastodon.localDomain = "ghuntley.com";
services.mastodon.extraConfig = {
ALTERNATE_DOMAINS = "geoffreyhuntley.com";
WEB_DOMAIN = "fediverse.ghuntley.com";
SINGLE_USER_MODE = "true";
EMAIL_DOMAIN_ALLOWLIST = "ghuntley.com";
RAILS_LOG_LEVEL = "debug";
};
services.mastodon.smtp.fromAddress = "[email protected]";
#services.mastodon.smtp.authenticate = true;
#services.mastodon.smtp.user = "[email protected]";
#services.mastodon.smtp.host = "smtp.mailgun.org";
#services.mastodon.smtp.port = 465;
virtualisation.oci-containers.containers = {
ghost = {
image = "ghost:5.8";
ports = [ "3001:2368" ];
volumes = [
"/srv/ghuntley.com/ghost:/var/lib/ghost/content:cached"
];
environment = {
url = "https://ghuntley.com";
};
};
};
systemd.services.docker-pull = {
serviceConfig.User = "root";
serviceConfig.Type = "oneshot";
path = [
pkgs.docker
pkgs.systemd
];
script = ''
${pkgs.docker}/bin/docker pull ghost
${pkgs.systemd}/bin/systemctl restart docker-ghost
'';
};
systemd.timers.docker-pull = {
wantedBy = [ "timers.target" ];
partOf = [ "updateghost.service" ];
timerConfig.OnCalendar = "daily";
};
services.postgresqlBackup.enable = true;
services.postgresqlBackup.databases = [ "mastodon" ];
services.postgresqlBackup.location = "/srv/postgresql";
systemd.services.backup = {
serviceConfig.User = "root";
serviceConfig.Type = "oneshot";
path = [
pkgs.rsync
pkgs.openssh
];
script = ''
${pkgs.rsync}/bin/rsync --archive --verbose --human-readable --delete-after --stats --compress /etc/nixos [email protected]:machines/ghuntley.net/etc/nixos
${pkgs.rsync}/bin/rsync --archive --verbose --human-readable --delete-after --stats --compress /srv [email protected]:machines/ghuntley.net/srv
${pkgs.rsync}/bin/rsync --archive --verbose --human-readable --delete-after --stats --compress /var/lib/mastodon [email protected]:machines/ghuntley.net/var/lib/mastodon
${pkgs.rsync}/bin/rsync --archive --verbose --human-readable --delete-after --stats --compress /var/lib/postgresql [email protected]:machines/ghuntley.net/var/lib/postgresql
${pkgs.rsync}/bin/rsync --archive --verbose --human-readable --delete-after --stats --compress /var/lib/elasticsearch [email protected]:machines/ghuntley.net/var/lib/elasticsearch
'';
};
systemd.timers.backup = {
wantedBy = [ "timers.target" ];
partOf = [ "prunebackups.service" ];
timerConfig.OnCalendar = "hourly";
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
networking.firewall.allowedUDPPorts = [ 80 443 60000 60001 60002 60003 60004 60005 60006 60007 60008 60009 60010 ];
networking.firewall.enable = true;
services.fail2ban.enable = true;
nix.autoOptimiseStore = true;
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
system.autoUpgrade.enable = true;
nixpkgs.config.allowUnfree = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It‘s perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "21.05"; # Did you read the comment?
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment