forked from M-Labs/it-infra
Compare commits
522 Commits
hydra-gith
...
master
|
@ -0,0 +1,56 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
makeBackup = pkgs.writeScript "make-backupdl" ''
|
||||||
|
#!${pkgs.bash}/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export PATH=${pkgs.rsync}/bin:${pkgs.openssh}/bin
|
||||||
|
|
||||||
|
FILENAME=backup-`${pkgs.coreutils}/bin/date +%F`.tar.bz2.gpg
|
||||||
|
|
||||||
|
ssh nixbld.m-labs.hk mlabs-backup > /hdd/backupdl/backupdl/$FILENAME
|
||||||
|
rsync -az nixbld.m-labs.hk:/var/lib/nextcloud/data /hdd/backupdl/nextcloud
|
||||||
|
'';
|
||||||
|
|
||||||
|
cfg = config.services.backupdl;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.backupdl = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable backups";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services.backupdl = {
|
||||||
|
description = "Nixbld backups download";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "backupdl";
|
||||||
|
Group = "backupdl";
|
||||||
|
ExecStart = "${makeBackup}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.backupdl = {
|
||||||
|
name = "backupdl";
|
||||||
|
group = "backupdl";
|
||||||
|
description = "Nixbld backups download";
|
||||||
|
isSystemUser = true;
|
||||||
|
createHome = true;
|
||||||
|
home = "/hdd/backupdl";
|
||||||
|
useDefaultShell = true;
|
||||||
|
};
|
||||||
|
users.extraGroups.backupdl = {};
|
||||||
|
|
||||||
|
systemd.timers.backupdl = {
|
||||||
|
description = "Nixbld backups download";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig.OnCalendar = "wednesday,sunday *-*-* 08:00:00";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
network:
|
||||||
|
version: 2
|
||||||
|
renderer: networkd
|
||||||
|
ethernets:
|
||||||
|
eth0:
|
||||||
|
addresses:
|
||||||
|
- 5.78.86.156/32
|
||||||
|
- 2a01:4ff:1f0:83de::2/64
|
||||||
|
- 2a01:4ff:1f0:83de::3/64
|
||||||
|
- 2a01:4ff:1f0:83de::4/64
|
||||||
|
tunnels:
|
||||||
|
gre1:
|
||||||
|
mode: gre
|
||||||
|
local: 5.78.86.156
|
||||||
|
remote: 94.190.212.123
|
||||||
|
addresses:
|
||||||
|
- 10.47.3.0/31
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
[Unit]
|
||||||
|
Description=GRE tunnel to the main host
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
ExecStart=/root/gretun.sh
|
||||||
|
ExecStop=/root/gretun_down.sh
|
||||||
|
Restart=on-failure
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
/usr/sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 25 -j DNAT --to-destination 10.47.3.1:25
|
||||||
|
/usr/sbin/iptables -A FORWARD -p tcp -d 10.47.3.1/31 --dport 25 -j ACCEPT
|
||||||
|
|
||||||
|
/usr/sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 587 -j DNAT --to-destination 10.47.3.1:587
|
||||||
|
/usr/sbin/iptables -A FORWARD -p tcp -d 10.47.3.1/31 --dport 587 -j ACCEPT
|
||||||
|
|
||||||
|
/usr/sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
/usr/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
/usr/sbin/iptables -t nat -D PREROUTING -p tcp -i eth0 --dport 25 -j DNAT --to-destination 10.47.3.1:25
|
||||||
|
/usr/sbin/iptables -D FORWARD -p tcp -d 10.47.3.1/31 --dport 25 -j ACCEPT
|
||||||
|
|
||||||
|
/usr/sbin/iptables -t nat -D PREROUTING -p tcp -i eth0 --dport 587 -j DNAT --to-destination 10.47.3.1:587
|
||||||
|
/usr/sbin/iptables -D FORWARD -p tcp -d 10.47.3.1/31 --dport 587 -j ACCEPT
|
||||||
|
|
||||||
|
/usr/sbin/iptables -D FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
/usr/sbin/iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
|
@ -0,0 +1,81 @@
|
||||||
|
upstream rfq_server {
|
||||||
|
server 127.0.0.1:5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
limit_conn addr 5;
|
||||||
|
|
||||||
|
root /var/www/m-labs-intl.com/html;
|
||||||
|
index index.html index.htm index.nginx-debian.html;
|
||||||
|
|
||||||
|
server_name m-labs-intl.com;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen [::]:443 ssl ipv6only=on; # managed by Certbot
|
||||||
|
listen 443 ssl; # managed by Certbot
|
||||||
|
ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/privkey.pem; # managed by Certbot
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
server_name www.m-labs-intl.com;
|
||||||
|
return 301 https://m-labs-intl.com$request_uri;
|
||||||
|
|
||||||
|
listen [::]:443 ssl; # managed by Certbot
|
||||||
|
listen 443 ssl; # managed by Certbot
|
||||||
|
ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/privkey.pem; # managed by Certbot
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
server_name hooks.m-labs-intl.com;
|
||||||
|
limit_conn addr 5;
|
||||||
|
|
||||||
|
location /rfq {
|
||||||
|
proxy_pass http://rfq_server/rfq;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
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_read_timeout 30;
|
||||||
|
proxy_connect_timeout 30;
|
||||||
|
proxy_send_timeout 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 418;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen [::]:443 ssl; # managed by Certbot
|
||||||
|
listen 443 ssl; # managed by Certbot
|
||||||
|
ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/privkey.pem; # managed by Certbot
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
limit_conn addr 5;
|
||||||
|
if ($host = m-labs-intl.com) {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
} # managed by Certbot
|
||||||
|
|
||||||
|
|
||||||
|
if ($host = www.m-labs-intl.com) {
|
||||||
|
return 301 https://m-labs-intl.com$request_uri;
|
||||||
|
} # managed by Certbot
|
||||||
|
|
||||||
|
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
server_name m-labs-intl.com www.m-labs-intl.com hooks.m-labs-intl.com;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
|
||||||
|
connections {
|
||||||
|
m_labs {
|
||||||
|
version = 2
|
||||||
|
encap = no
|
||||||
|
mobike = no
|
||||||
|
send_certreq = no
|
||||||
|
proposals = aes128gcm128-sha256-prfsha256-curve25519,aes128gcm128-sha256-prfsha256-ecp256
|
||||||
|
local_addrs = 5.78.86.156
|
||||||
|
remote_addrs = 94.190.212.123
|
||||||
|
local {
|
||||||
|
auth = pubkey
|
||||||
|
id = fqdn:m-labs-intl.com
|
||||||
|
pubkeys = m-labs-intl.com
|
||||||
|
}
|
||||||
|
remote {
|
||||||
|
auth = pubkey
|
||||||
|
id = fqdn:m-labs.hk
|
||||||
|
pubkeys = m-labs.hk
|
||||||
|
}
|
||||||
|
children {
|
||||||
|
con1 {
|
||||||
|
mode = transport
|
||||||
|
ah_proposals = sha256-curve25519,sha256-ecp256
|
||||||
|
esp_proposals =
|
||||||
|
local_ts = 5.78.86.156[gre]
|
||||||
|
remote_ts = 94.190.212.123[gre]
|
||||||
|
start_action = start
|
||||||
|
close_action = none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
user www-data;
|
||||||
|
worker_processes auto;
|
||||||
|
pid /run/nginx.pid;
|
||||||
|
error_log /var/log/nginx/error.log;
|
||||||
|
include /etc/nginx/modules-enabled/*.conf;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 768;
|
||||||
|
# multi_accept on;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
|
||||||
|
##
|
||||||
|
# Basic Settings
|
||||||
|
##
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
# server_tokens off;
|
||||||
|
|
||||||
|
server_names_hash_bucket_size 64;
|
||||||
|
# server_name_in_redirect off;
|
||||||
|
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
##
|
||||||
|
# SSL Settings
|
||||||
|
##
|
||||||
|
|
||||||
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
# Rate limiting
|
||||||
|
limit_conn_zone $binary_remote_addr zone=addr:10m;
|
||||||
|
|
||||||
|
##
|
||||||
|
# Logging Settings
|
||||||
|
##
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log;
|
||||||
|
|
||||||
|
##
|
||||||
|
# Gzip Settings
|
||||||
|
##
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
|
||||||
|
# gzip_vary on;
|
||||||
|
# gzip_proxied any;
|
||||||
|
# gzip_comp_level 6;
|
||||||
|
# gzip_buffers 16 8k;
|
||||||
|
# gzip_http_version 1.1;
|
||||||
|
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||||
|
|
||||||
|
##
|
||||||
|
# Virtual Host Configs
|
||||||
|
##
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
include /etc/nginx/sites-enabled/*;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
[Unit]
|
||||||
|
Description=RFQ service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=rfqserver
|
||||||
|
ExecStart=/home/rfqserver/runrfq.sh
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
export FLASK_DEBUG=0
|
||||||
|
export FLASK_MAIL_SERVER=mail.m-labs.hk
|
||||||
|
export FLASK_MAIL_PORT=465
|
||||||
|
export FLASK_MAIL_USE_SSL=True
|
||||||
|
export FLASK_MAIL_USERNAME=sysop-intl@m-labs-intl.com
|
||||||
|
export FLASK_MAIL_PASSWORD_FILE=/home/rfqserver/mail.secret
|
||||||
|
export FLASK_MAIL_RECIPIENT=sales@m-labs.hk
|
||||||
|
export FLASK_MAIL_SENDER=sysop-intl@m-labs-intl.com
|
||||||
|
|
||||||
|
cd /home/rfqserver/web2019/server
|
||||||
|
source venv/bin/activate
|
||||||
|
python3 -m flask --app rfq run --port=5000
|
|
@ -0,0 +1,99 @@
|
||||||
|
# Setup m-labs-intl.com server
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Install required packages
|
||||||
|
apt install git nginx-full python3 python3.12-venv python3-pip iptables ufw \
|
||||||
|
strongswan strongswan-swanctl strongswan-pki strongswan-libcharon
|
||||||
|
snap install --classic certbot
|
||||||
|
ln -s /snap/bin/certbot /usr/bin/certbot
|
||||||
|
|
||||||
|
# Set up networks (includes GRE)
|
||||||
|
cp 60-tunnels.yaml /etc/netplan/
|
||||||
|
netplan apply
|
||||||
|
|
||||||
|
# set up IPsec-AH connection
|
||||||
|
cp m-labs.hk.conf /etc/swanctl/conf.d/
|
||||||
|
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
|
||||||
|
sysctl -p
|
||||||
|
cp m-labs.hk /etc/swanctl/pubkey/m-labs.hk # get pubkey from nixbld
|
||||||
|
pki --gen --type rsa --size 4096 --outform pem > /etc/swanctl/private/m-labs-intl.com
|
||||||
|
pki --pub --in /etc/swanctl/private/m-labs-intl.com --outform pem > /etc/swanctl/pubkey/m-labs-intl.com
|
||||||
|
cp /etc/swanctl/pubkey/m-labs-intl.com m-labs-intl.com # add it to the nixbld
|
||||||
|
systemctl enable strongswan --now
|
||||||
|
systemctl restart strongswan
|
||||||
|
|
||||||
|
# Set up website
|
||||||
|
cp m-labs-intl.com /etc/nginx/sites-available/
|
||||||
|
cp nginx.conf /etc/nginx/
|
||||||
|
ln -s /etc/nginx/sites-available/m-labs-intl.com /etc/nginx/sites-enabled/
|
||||||
|
systemctl enable nginx --now
|
||||||
|
service nginx restart
|
||||||
|
|
||||||
|
# Issue SSL certificate - website only, the mail is on the HK side
|
||||||
|
certbot --nginx
|
||||||
|
service nginx restart
|
||||||
|
|
||||||
|
# Create a user for automatic website deployment from nixbld
|
||||||
|
useradd -m zolaupd
|
||||||
|
mkdir -p /var/www/m-labs-intl.com/html
|
||||||
|
chown -R zolaupd /var/www/m-labs-intl.com/
|
||||||
|
sudo -u zolaupd sh -c '
|
||||||
|
cd /home/zolaupd;
|
||||||
|
mkdir /home/zolaupd/.ssh;
|
||||||
|
echo -n "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP1OJJM8g/1ffxDjN31XKEfGmrYaW03lwpyTa1UGWqVx
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF6R6XK0IiuAKxVKvSABm4m9bfOlvfJcMvTpjenuXUPv" > /home/zolaupd/.ssh/authorized_keys
|
||||||
|
chmod 700 .ssh/
|
||||||
|
chmod 600 .ssh/authorized_keys
|
||||||
|
'
|
||||||
|
|
||||||
|
# Create a user for RFQ hooks service
|
||||||
|
useradd -m rfqserver
|
||||||
|
cp runrfq.sh /home/rfqserver/
|
||||||
|
cp mail.secret /home/rfqserver/
|
||||||
|
chown rfqserver /home/rfqserver/runrfq.sh
|
||||||
|
chmod +x /home/rfqserver/runrfq.sh
|
||||||
|
chown rfqserver /home/rfqserver/mail.secret
|
||||||
|
|
||||||
|
sudo -u rfqserver sh -c '
|
||||||
|
cd /home/rfqserver;
|
||||||
|
git clone https://git.m-labs.hk/M-Labs/web2019.git;
|
||||||
|
cd web2019;
|
||||||
|
python3 -m venv ./venv;
|
||||||
|
source venv/bin/activate;
|
||||||
|
pip install -r requirements.txt;
|
||||||
|
'
|
||||||
|
cp rfq.service /etc/systemd/system/
|
||||||
|
|
||||||
|
# Automate port forwarding rules creation
|
||||||
|
cp gretun.sh /root/gretun.sh
|
||||||
|
cp gretun_down.sh /root/gretun_down.sh
|
||||||
|
chmod u+x /root/gretun.sh
|
||||||
|
chmod u+x /root/gretun_down.sh
|
||||||
|
cp gretun.service /etc/systemd/system/
|
||||||
|
|
||||||
|
# Enable custom services
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable rfq.service --now
|
||||||
|
systemctl enable gretun.service --now
|
||||||
|
|
||||||
|
# Setup basic firewall rules
|
||||||
|
ufw default deny
|
||||||
|
ufw default allow outgoing
|
||||||
|
|
||||||
|
ufw allow from 94.190.212.123
|
||||||
|
ufw allow from 2001:470:f891:1::/64
|
||||||
|
ufw allow from 202.77.7.238
|
||||||
|
ufw allow from 2001:470:18:390::2
|
||||||
|
ufw allow "Nginx HTTP"
|
||||||
|
ufw allow "Nginx HTTPS"
|
||||||
|
ufw limit OpenSSH
|
||||||
|
ufw allow 25/tcp
|
||||||
|
ufw allow 587/tcp
|
||||||
|
ufw limit 500,4500/udp
|
||||||
|
|
||||||
|
ufw route allow in on gre1 out on eth0
|
||||||
|
ufw allow from 10.47.3.0/31
|
||||||
|
|
||||||
|
ufw show added
|
||||||
|
ufw enable
|
||||||
|
```
|
|
@ -0,0 +1,66 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
afws = pkgs.callPackage ./afws { inherit pkgs; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.afws = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable AFWS server";
|
||||||
|
};
|
||||||
|
logFile = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/var/lib/afws/logs/afws.log";
|
||||||
|
description = "Path to the log file";
|
||||||
|
};
|
||||||
|
logBackupCount = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 30;
|
||||||
|
description = "Number of daily log files to keep";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.services.afws.enable {
|
||||||
|
systemd.services.afws = {
|
||||||
|
description = "AFWS server";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
preStart = ''
|
||||||
|
mkdir -p "$(dirname ${config.services.afws.logFile})"
|
||||||
|
chown afws:afws "$(dirname ${config.services.afws.logFile})"
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
User = "afws";
|
||||||
|
Group = "afws";
|
||||||
|
ExecStart = ''
|
||||||
|
${afws}/bin/afws_server \
|
||||||
|
--log-file ${config.services.afws.logFile} \
|
||||||
|
--log-backup-count ${toString config.services.afws.logBackupCount}
|
||||||
|
'';
|
||||||
|
ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
|
||||||
|
};
|
||||||
|
path = [ pkgs.nix pkgs.git ];
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme.certs."afws.m-labs.hk".postRun =
|
||||||
|
''
|
||||||
|
mkdir -p /var/lib/afws/cert
|
||||||
|
cp cert.pem /var/lib/afws/cert
|
||||||
|
cp key.pem /var/lib/afws/cert
|
||||||
|
chown -R afws:afws /var/lib/afws/cert
|
||||||
|
'';
|
||||||
|
security.acme.certs."afws.m-labs.hk".reloadServices = [ "afws.service" ];
|
||||||
|
|
||||||
|
users.users.afws = {
|
||||||
|
name = "afws";
|
||||||
|
group = "afws";
|
||||||
|
description = "AFWS server user";
|
||||||
|
isSystemUser = true;
|
||||||
|
createHome = false;
|
||||||
|
home = "/var/lib/afws";
|
||||||
|
useDefaultShell = true;
|
||||||
|
};
|
||||||
|
users.extraGroups.afws = {};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,30 +1,37 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
excludePaths = [
|
||||||
|
"/var/lib/gitea/repositories/*/*.git/archives"
|
||||||
|
"/var/lib/gitea/data/repo-archive"
|
||||||
|
"/var/lib/gitea/data/indexers"
|
||||||
|
"/var/vmail/m-labs.hk/js"
|
||||||
|
"/var/lib/afws/.cache"
|
||||||
|
"/var/lib/mattermost/data/2019*"
|
||||||
|
"/var/lib/mattermost/data/2020*"
|
||||||
|
"/var/lib/mattermost/data/2021*"
|
||||||
|
"/var/lib/mattermost/data/2022*"
|
||||||
|
"/var/lib/mattermost/data/2023*"
|
||||||
|
];
|
||||||
makeBackup = pkgs.writeScript "make-backup" ''
|
makeBackup = pkgs.writeScript "make-backup" ''
|
||||||
#!${pkgs.bash}/bin/bash
|
#!${pkgs.bash}/bin/bash -p
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
umask 0077
|
umask 0077
|
||||||
|
|
||||||
FILENAME=backup-`date +%F`.tar.bz2.gpg
|
|
||||||
|
|
||||||
DBDUMPDIR=`mktemp -d`
|
DBDUMPDIR=`mktemp -d`
|
||||||
pushd $DBDUMPDIR
|
trap "rm -rf $DBDUMPDIR" EXIT
|
||||||
|
cd $DBDUMPDIR
|
||||||
|
|
||||||
${config.services.mysql.package}/bin/mysqldump --single-transaction flarum > flarum.sql
|
${config.services.mysql.package}/bin/mysqldump --user=root --single-transaction flarum > flarum.sql
|
||||||
${pkgs.sudo}/bin/sudo -u mattermost ${config.services.postgresql.package}/bin/pg_dump mattermost > mattermost.sql
|
${config.services.postgresql.package}/bin/pg_dump mattermost > mattermost.sql
|
||||||
|
${config.services.postgresql.package}/bin/pg_dump rt5 > rt.sql
|
||||||
|
${config.services.postgresql.package}/bin/pg_dump gitea > gitea.sql
|
||||||
|
|
||||||
${pkgs.gnutar}/bin/tar cf - --exclude "/var/lib/gitea/repositories/*/*.git/archives" /etc/nixos /var/lib/gitea flarum.sql mattermost.sql | \
|
exec 6< /etc/nixos/secret/backup-passphrase
|
||||||
|
${pkgs.gnutar}/bin/tar cf - ${lib.concatMapStringsSep " " (p: "--exclude \"${p}\"") excludePaths} /etc/nixos /var/vmail /var/lib/hedgedoc /var/lib/gitea /var/lib/afws /var/lib/mattermost/data /var/www/193thz flarum.sql mattermost.sql rt.sql gitea.sql | \
|
||||||
${pkgs.bzip2}/bin/bzip2 | \
|
${pkgs.bzip2}/bin/bzip2 | \
|
||||||
${pkgs.gnupg}/bin/gpg --symmetric --batch --passphrase-file /etc/nixos/secret/backup-passphrase | \
|
${pkgs.gnupg}/bin/gpg --symmetric --batch --passphrase-fd 6
|
||||||
tee --output-error=warn /tank/backup/$FILENAME | \
|
|
||||||
${pkgs.rclone}/bin/rclone rcat --config /etc/nixos/secret/rclone.conf dropbox:$FILENAME
|
|
||||||
|
|
||||||
popd
|
|
||||||
rm -rf $DBDUMPDIR
|
|
||||||
|
|
||||||
echo Backup done
|
|
||||||
'';
|
'';
|
||||||
cfg = config.services.mlabs-backup;
|
cfg = config.services.mlabs-backup;
|
||||||
in
|
in
|
||||||
|
@ -38,20 +45,20 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.mlabs-backup = {
|
users.extraGroups.backupdl = { };
|
||||||
description = "M-Labs backup";
|
users.extraUsers.backupdl = {
|
||||||
serviceConfig = {
|
isNormalUser = true;
|
||||||
Type = "oneshot";
|
extraGroups = ["backupdl" "nextcloud"];
|
||||||
User = "root";
|
openssh.authorizedKeys.keys = [
|
||||||
Group = "root";
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCbH+l0FIBTPdUKOS9H5OOT5ro/nljKLsiCTzTzublCScdPPmCNy27ORbLgNHX5Ughlug5wr2rAIU9AexV+L71V5MeVHUWDfKgRsNIpUTtY6wpJkAP7r1ipk2kTWc/sxhrxyPea62cohmy1dOeLlwXO6U8FnsiZfYKmgjZ8wuTo6ixDB8krXsAZ8VY/bj5WFcXqeW8GF1Qjpel7HgpCpj3HIUyC63uwIyUoYe+cgnhjzNLbRYdU9Yx2iqcUCwEUX2cMdz5VX+xbLkL8CWcuiMFg6TFo+CUPFtuA/kVzHcZ4Pa3BiilL3rf7oXlIXGN12JVsN+caX7j2weVqm2b5u5eVsyDxiLx1KA37ukq92CYAAdOuKE+saMPsLuOn+Qd9B6D5oYnYgsWg460uEGgwczwOTXLAZTT5wrwRaKIE+ezKqtRP+Tz7l2IEixulyj1MUR+XpSwECZXiFJx5DGofwzxcd2kWnNOPBReDkHv0At5ZLNIrLuxFMz2L6UXbqvHwEu8= backupdl@minipc"
|
||||||
ExecStart = "${makeBackup}";
|
];
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
security.wrappers.mlabs-backup = {
|
||||||
systemd.timers.mlabs-backup = {
|
source = makeBackup;
|
||||||
description = "M-Labs backup";
|
setuid = true;
|
||||||
wantedBy = [ "timers.target" ];
|
owner = "root";
|
||||||
timerConfig.OnCalendar = "weekly";
|
group = "backupdl";
|
||||||
|
permissions = "g+x";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,29 +0,0 @@
|
||||||
# Run with: nix-shell flarum-update.nix
|
|
||||||
|
|
||||||
{ pkgs ? import <nixpkgs> {}
|
|
||||||
}:
|
|
||||||
|
|
||||||
with pkgs;
|
|
||||||
let
|
|
||||||
composer2nix = import (fetchFromGitHub {
|
|
||||||
owner = "svanderburg";
|
|
||||||
repo = "composer2nix";
|
|
||||||
rev = "v0.0.4";
|
|
||||||
sha256 = "0q0x3in43ss1p0drhc5lp5bnp2jqni1i7zxm7lmjl5aad9nkn3gf";
|
|
||||||
}) { inherit pkgs; };
|
|
||||||
in
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
name = "flarum-update";
|
|
||||||
buildInputs = [ phpPackages.composer composer2nix ];
|
|
||||||
shellHook = ''
|
|
||||||
OUT=$(pwd)/flarum
|
|
||||||
|
|
||||||
cd $(mktemp -d)
|
|
||||||
composer create-project flarum/flarum . --stability=beta
|
|
||||||
composer require fof/upload
|
|
||||||
|
|
||||||
composer2nix
|
|
||||||
cp -v *.nix composer.{json,lock} $OUT/
|
|
||||||
exit
|
|
||||||
'';
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
let
|
|
||||||
flarumPackage = with pkgs; stdenv.mkDerivation {
|
|
||||||
name = "flarum-package";
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "flarum";
|
|
||||||
repo = "flarum";
|
|
||||||
rev = "v0.1.0-beta.13";
|
|
||||||
sha256 = "0mj6w7nibdqmi7lx2r5d9yiif6lb584l93551i115a9ly3s4yinn";
|
|
||||||
};
|
|
||||||
buildPhase =
|
|
||||||
''
|
|
||||||
cp ${./flarum}/* .
|
|
||||||
'';
|
|
||||||
installPhase =
|
|
||||||
''
|
|
||||||
cp -ar . $out
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
flarum = import "${flarumPackage}" {
|
|
||||||
inherit pkgs;
|
|
||||||
noDev = true;
|
|
||||||
};
|
|
||||||
cfg = config.services.flarum;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.services.flarum = with pkgs.lib; {
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "nobody";
|
|
||||||
};
|
|
||||||
group = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "nogroup";
|
|
||||||
};
|
|
||||||
installPath = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/var/www/flarum";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config.systemd.services.flarum-install = {
|
|
||||||
description = "Flarum installation";
|
|
||||||
before = [ "nginx.service" "phpfm-flarum.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
};
|
|
||||||
path = [ pkgs.rsync ];
|
|
||||||
script = with cfg; ''
|
|
||||||
mkdir -p ${installPath}
|
|
||||||
rsync --links --recursive ${flarum}/ ${installPath}
|
|
||||||
for d in ${installPath} ${installPath}/public/assets \
|
|
||||||
${installPath}/storage ${installPath}/storage/*
|
|
||||||
do
|
|
||||||
chown ${user}:${group} $d
|
|
||||||
chmod 0775 $d
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,238 +0,0 @@
|
||||||
# This file originates from composer2nix
|
|
||||||
|
|
||||||
{ stdenv, writeTextFile, fetchurl, php, unzip, phpPackages }:
|
|
||||||
|
|
||||||
let
|
|
||||||
inherit (phpPackages) composer;
|
|
||||||
buildZipPackage = { name, src }:
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
inherit name src;
|
|
||||||
buildInputs = [ unzip ];
|
|
||||||
buildCommand = ''
|
|
||||||
unzip $src
|
|
||||||
baseDir=$(find . -type d -mindepth 1 -maxdepth 1)
|
|
||||||
cd $baseDir
|
|
||||||
mkdir -p $out
|
|
||||||
mv * $out
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
buildPackage =
|
|
||||||
{ name
|
|
||||||
, src
|
|
||||||
, packages ? {}
|
|
||||||
, devPackages ? {}
|
|
||||||
, buildInputs ? []
|
|
||||||
, symlinkDependencies ? false
|
|
||||||
, executable ? false
|
|
||||||
, removeComposerArtifacts ? false
|
|
||||||
, postInstall ? ""
|
|
||||||
, noDev ? false
|
|
||||||
, unpackPhase ? "true"
|
|
||||||
, buildPhase ? "true"
|
|
||||||
, ...}@args:
|
|
||||||
|
|
||||||
let
|
|
||||||
reconstructInstalled = writeTextFile {
|
|
||||||
name = "reconstructinstalled.php";
|
|
||||||
executable = true;
|
|
||||||
text = ''
|
|
||||||
#! ${php}/bin/php
|
|
||||||
<?php
|
|
||||||
if(file_exists($argv[1]))
|
|
||||||
{
|
|
||||||
$composerLockStr = file_get_contents($argv[1]);
|
|
||||||
|
|
||||||
if($composerLockStr === false)
|
|
||||||
{
|
|
||||||
fwrite(STDERR, "Cannot open composer.lock contents\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$config = json_decode($composerLockStr, true);
|
|
||||||
|
|
||||||
if(array_key_exists("packages", $config))
|
|
||||||
$allPackages = $config["packages"];
|
|
||||||
else
|
|
||||||
$allPackages = array();
|
|
||||||
|
|
||||||
${stdenv.lib.optionalString (!noDev) ''
|
|
||||||
if(array_key_exists("packages-dev", $config))
|
|
||||||
$allPackages = array_merge($allPackages, $config["packages-dev"]);
|
|
||||||
''}
|
|
||||||
|
|
||||||
$packagesStr = json_encode($allPackages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
|
||||||
print($packagesStr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
print("[]");
|
|
||||||
?>
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
constructBin = writeTextFile {
|
|
||||||
name = "constructbin.php";
|
|
||||||
executable = true;
|
|
||||||
text = ''
|
|
||||||
#! ${php}/bin/php
|
|
||||||
<?php
|
|
||||||
$composerJSONStr = file_get_contents($argv[1]);
|
|
||||||
|
|
||||||
if($composerJSONStr === false)
|
|
||||||
{
|
|
||||||
fwrite(STDERR, "Cannot open composer.json contents\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$config = json_decode($composerJSONStr, true);
|
|
||||||
|
|
||||||
if(array_key_exists("bin-dir", $config))
|
|
||||||
$binDir = $config["bin-dir"];
|
|
||||||
else
|
|
||||||
$binDir = "bin";
|
|
||||||
|
|
||||||
if(array_key_exists("bin", $config))
|
|
||||||
{
|
|
||||||
if(!file_exists("vendor/".$binDir))
|
|
||||||
mkdir("vendor/".$binDir);
|
|
||||||
|
|
||||||
foreach($config["bin"] as $bin)
|
|
||||||
symlink("../../".$bin, "vendor/".$binDir."/".basename($bin));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
bundleDependencies = dependencies:
|
|
||||||
stdenv.lib.concatMapStrings (dependencyName:
|
|
||||||
let
|
|
||||||
dependency = dependencies.${dependencyName};
|
|
||||||
in
|
|
||||||
''
|
|
||||||
${if dependency.targetDir == "" then ''
|
|
||||||
vendorDir="$(dirname ${dependencyName})"
|
|
||||||
mkdir -p "$vendorDir"
|
|
||||||
${if symlinkDependencies then
|
|
||||||
''ln -s "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
|
|
||||||
else
|
|
||||||
''cp -av "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
|
|
||||||
}
|
|
||||||
'' else ''
|
|
||||||
namespaceDir="${dependencyName}/$(dirname "${dependency.targetDir}")"
|
|
||||||
mkdir -p "$namespaceDir"
|
|
||||||
${if symlinkDependencies then
|
|
||||||
''ln -s "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
|
|
||||||
else
|
|
||||||
''cp -av "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
|
|
||||||
}
|
|
||||||
''}
|
|
||||||
'') (builtins.attrNames dependencies);
|
|
||||||
|
|
||||||
extraArgs = removeAttrs args [ "name" "packages" "devPackages" "buildInputs" ];
|
|
||||||
in
|
|
||||||
stdenv.mkDerivation ({
|
|
||||||
name = "composer-${name}";
|
|
||||||
buildInputs = [ php composer ] ++ buildInputs;
|
|
||||||
|
|
||||||
inherit unpackPhase buildPhase;
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
${if executable then ''
|
|
||||||
mkdir -p $out/share/php
|
|
||||||
cp -av $src $out/share/php/$name
|
|
||||||
chmod -R u+w $out/share/php/$name
|
|
||||||
cd $out/share/php/$name
|
|
||||||
'' else ''
|
|
||||||
cp -av $src $out
|
|
||||||
chmod -R u+w $out
|
|
||||||
cd $out
|
|
||||||
''}
|
|
||||||
|
|
||||||
# Remove unwanted files
|
|
||||||
rm -f *.nix
|
|
||||||
|
|
||||||
export HOME=$TMPDIR
|
|
||||||
|
|
||||||
# Remove the provided vendor folder if it exists
|
|
||||||
rm -Rf vendor
|
|
||||||
|
|
||||||
# If there is no composer.lock file, compose a dummy file.
|
|
||||||
# Otherwise, composer attempts to download the package.json file from
|
|
||||||
# the registry which we do not want.
|
|
||||||
if [ ! -f composer.lock ]
|
|
||||||
then
|
|
||||||
cat > composer.lock <<EOF
|
|
||||||
{
|
|
||||||
"packages": []
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Reconstruct the installed.json file from the lock file
|
|
||||||
mkdir -p vendor/composer
|
|
||||||
${reconstructInstalled} composer.lock > vendor/composer/installed.json
|
|
||||||
|
|
||||||
# Copy or symlink the provided dependencies
|
|
||||||
cd vendor
|
|
||||||
${bundleDependencies packages}
|
|
||||||
${stdenv.lib.optionalString (!noDev) (bundleDependencies devPackages)}
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
# Reconstruct autoload scripts
|
|
||||||
# We use the optimize feature because Nix packages cannot change after they have been built
|
|
||||||
# Using the dynamic loader for a Nix package is useless since there is nothing to dynamically reload.
|
|
||||||
composer dump-autoload --optimize ${stdenv.lib.optionalString noDev "--no-dev"}
|
|
||||||
|
|
||||||
# Run the install step as a validation to confirm that everything works out as expected
|
|
||||||
composer install --optimize-autoloader ${stdenv.lib.optionalString noDev "--no-dev"}
|
|
||||||
|
|
||||||
${stdenv.lib.optionalString executable ''
|
|
||||||
# Reconstruct the bin/ folder if we deploy an executable project
|
|
||||||
${constructBin} composer.json
|
|
||||||
ln -s $(pwd)/vendor/bin $out/bin
|
|
||||||
''}
|
|
||||||
|
|
||||||
${stdenv.lib.optionalString (!symlinkDependencies) ''
|
|
||||||
# Patch the shebangs if possible
|
|
||||||
if [ -d $(pwd)/vendor/bin ]
|
|
||||||
then
|
|
||||||
# Look for all executables in bin/
|
|
||||||
for i in $(pwd)/vendor/bin/*
|
|
||||||
do
|
|
||||||
# Look for their location
|
|
||||||
realFile=$(readlink -f "$i")
|
|
||||||
|
|
||||||
# Restore write permissions
|
|
||||||
chmod u+wx "$(dirname "$realFile")"
|
|
||||||
chmod u+w "$realFile"
|
|
||||||
|
|
||||||
# Patch shebang
|
|
||||||
sed -e "s|#!/usr/bin/php|#!${php}/bin/php|" \
|
|
||||||
-e "s|#!/usr/bin/env php|#!${php}/bin/php|" \
|
|
||||||
"$realFile" > tmp
|
|
||||||
mv tmp "$realFile"
|
|
||||||
chmod u+x "$realFile"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
''}
|
|
||||||
|
|
||||||
if [ "$removeComposerArtifacts" = "1" ]
|
|
||||||
then
|
|
||||||
# Remove composer stuff
|
|
||||||
rm -f composer.json composer.lock
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Execute post install hook
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
} // extraArgs);
|
|
||||||
in
|
|
||||||
{
|
|
||||||
composer = stdenv.lib.makeOverridable composer;
|
|
||||||
buildZipPackage = stdenv.lib.makeOverridable buildZipPackage;
|
|
||||||
buildPackage = stdenv.lib.makeOverridable buildPackage;
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
{
|
|
||||||
"name": "flarum/flarum",
|
|
||||||
"description": "Delightfully simple forum software.",
|
|
||||||
"type": "project",
|
|
||||||
"keywords": [
|
|
||||||
"forum",
|
|
||||||
"discussion"
|
|
||||||
],
|
|
||||||
"homepage": "https://flarum.org/",
|
|
||||||
"license": "MIT",
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Franz Liedke",
|
|
||||||
"email": "franz@develophp.org"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Daniel Klabbers",
|
|
||||||
"email": "daniel@klabbers.email",
|
|
||||||
"homepage": "https://luceos.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "David Sevilla Martin",
|
|
||||||
"email": "me+flarum@datitisev.me",
|
|
||||||
"homepage": "https://datitisev.me"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Clark Winkelmann",
|
|
||||||
"email": "clark.winkelmann@gmail.com",
|
|
||||||
"homepage": "https://clarkwinkelmann.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Matthew Kilgore",
|
|
||||||
"email": "matthew@kilgore.dev"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/flarum/core/issues",
|
|
||||||
"source": "https://github.com/flarum/flarum",
|
|
||||||
"docs": "https://flarum.org/docs/"
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"flarum/approval": "^0.1.0",
|
|
||||||
"flarum/auth-facebook": "^0.1.0",
|
|
||||||
"flarum/auth-github": "^0.1.0",
|
|
||||||
"flarum/auth-twitter": "^0.1.0",
|
|
||||||
"flarum/bbcode": "^0.1.0",
|
|
||||||
"flarum/core": "^0.1.0",
|
|
||||||
"flarum/emoji": "^0.1.0",
|
|
||||||
"flarum/flags": "^0.1.0",
|
|
||||||
"flarum/lang-english": "^0.1.0",
|
|
||||||
"flarum/likes": "^0.1.0",
|
|
||||||
"flarum/lock": "^0.1.0",
|
|
||||||
"flarum/markdown": "^0.1.0",
|
|
||||||
"flarum/mentions": "^0.1.0",
|
|
||||||
"flarum/pusher": "^0.1.0",
|
|
||||||
"flarum/statistics": "^0.1.0",
|
|
||||||
"flarum/sticky": "^0.1.0",
|
|
||||||
"flarum/subscriptions": "^0.1.0",
|
|
||||||
"flarum/suspend": "^0.1.0",
|
|
||||||
"flarum/tags": "^0.1.0",
|
|
||||||
"fof/upload": "^0.10.0"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"preferred-install": "dist",
|
|
||||||
"sort-packages": true
|
|
||||||
},
|
|
||||||
"minimum-stability": "beta",
|
|
||||||
"prefer-stable": true
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,39 @@
|
||||||
{pkgs ? import <nixpkgs> {
|
{
|
||||||
inherit system;
|
lib,
|
||||||
}, system ? builtins.currentSystem, noDev ? false}:
|
php,
|
||||||
|
fetchFromGitHub,
|
||||||
|
fetchpatch,
|
||||||
|
}:
|
||||||
|
|
||||||
let
|
php.buildComposerProject (finalAttrs: {
|
||||||
composerEnv = import ./composer-env.nix {
|
pname = "flarum";
|
||||||
inherit (pkgs) stdenv writeTextFile fetchurl php unzip phpPackages;
|
version = "1.8.1";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "flarum";
|
||||||
|
repo = "flarum";
|
||||||
|
rev = "v${finalAttrs.version}";
|
||||||
|
hash = "sha256-kigUZpiHTM24XSz33VQYdeulG1YI5s/M02V7xue72VM=";
|
||||||
};
|
};
|
||||||
in
|
|
||||||
import ./php-packages.nix {
|
patches = [
|
||||||
inherit composerEnv noDev;
|
# Add useful extensions from https://github.com/FriendsOfFlarum
|
||||||
inherit (pkgs) fetchurl fetchgit fetchhg fetchsvn;
|
# Extensions included: fof/upload, fof/polls, fof/subscribed
|
||||||
}
|
./fof-extensions.patch
|
||||||
|
];
|
||||||
|
|
||||||
|
composerLock = ./composer.lock;
|
||||||
|
composerStrictValidation = false;
|
||||||
|
vendorHash = "sha256-z3KVGmILw8MZ4aaSf6IP/0l16LI/Y2yMzY2KMHf4qSg=";
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
changelog = "https://github.com/flarum/framework/blob/main/CHANGELOG.md";
|
||||||
|
description = "Flarum is a delightfully simple discussion platform for your website";
|
||||||
|
homepage = "https://github.com/flarum/flarum";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
maintainers = with maintainers; [
|
||||||
|
fsagbuya
|
||||||
|
jasonodoom
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
diff --git a/composer.json b/composer.json
|
||||||
|
index c63b5f8..5ad1186 100644
|
||||||
|
--- a/composer.json
|
||||||
|
+++ b/composer.json
|
||||||
|
@@ -37,7 +37,10 @@
|
||||||
|
"flarum/sticky": "*",
|
||||||
|
"flarum/subscriptions": "*",
|
||||||
|
"flarum/suspend": "*",
|
||||||
|
- "flarum/tags": "*"
|
||||||
|
+ "flarum/tags": "*",
|
||||||
|
+ "fof/polls": "*",
|
||||||
|
+ "fof/subscribed": "*",
|
||||||
|
+ "fof/upload": "*"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"preferred-install": "dist",
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,61 @@
|
||||||
|
diff --git a/github_backup/github_backup.py b/github_backup/github_backup.py
|
||||||
|
index 4ef8b7e..82cbdca 100644
|
||||||
|
--- a/github_backup/github_backup.py
|
||||||
|
+++ b/github_backup/github_backup.py
|
||||||
|
@@ -425,7 +425,7 @@ def get_github_repo_url(args, repository):
|
||||||
|
return repo_url
|
||||||
|
|
||||||
|
|
||||||
|
-def retrieve_data_gen(args, template, query_args=None, single_request=False):
|
||||||
|
+def retrieve_data_gen(args, template, query_args=None, single_request=False, optional=False):
|
||||||
|
auth = get_auth(args, encode=not args.as_app)
|
||||||
|
query_args = get_query_args(query_args)
|
||||||
|
per_page = 100
|
||||||
|
@@ -452,6 +452,11 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
|
||||||
|
else:
|
||||||
|
read_error = False
|
||||||
|
|
||||||
|
+ # Requested data does not exist for this repository, but that was expected.
|
||||||
|
+ # Generate an empty list.
|
||||||
|
+ if status_code == 404 and optional:
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
# be gentle with API request limit and throttle requests if remaining requests getting low
|
||||||
|
limit_remaining = int(r.headers.get('x-ratelimit-remaining', 0))
|
||||||
|
if args.throttle_limit and limit_remaining <= args.throttle_limit:
|
||||||
|
@@ -509,8 +514,8 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
-def retrieve_data(args, template, query_args=None, single_request=False):
|
||||||
|
- return list(retrieve_data_gen(args, template, query_args, single_request))
|
||||||
|
+def retrieve_data(args, template, query_args=None, single_request=False, optional=False):
|
||||||
|
+ return list(retrieve_data_gen(args, template, query_args, single_request, optional))
|
||||||
|
|
||||||
|
|
||||||
|
def get_query_args(query_args=None):
|
||||||
|
@@ -1011,7 +1016,8 @@ def backup_hooks(args, repo_cwd, repository, repos_template):
|
||||||
|
'hooks',
|
||||||
|
template,
|
||||||
|
output_file,
|
||||||
|
- hook_cwd)
|
||||||
|
+ hook_cwd,
|
||||||
|
+ optional=not args.include_hooks)
|
||||||
|
except SystemExit:
|
||||||
|
log_info("Unable to read hooks, skipping")
|
||||||
|
|
||||||
|
@@ -1158,12 +1164,12 @@ def backup_account(args, output_directory):
|
||||||
|
account_cwd)
|
||||||
|
|
||||||
|
|
||||||
|
-def _backup_data(args, name, template, output_file, output_directory):
|
||||||
|
+def _backup_data(args, name, template, output_file, output_directory, optional=False):
|
||||||
|
skip_existing = args.skip_existing
|
||||||
|
if not skip_existing or not os.path.exists(output_file):
|
||||||
|
log_info('Retrieving {0} {1}'.format(args.user, name))
|
||||||
|
mkdir_p(output_directory)
|
||||||
|
- data = retrieve_data(args, template)
|
||||||
|
+ data = retrieve_data(args, template, optional=optional)
|
||||||
|
|
||||||
|
log_info('Writing {0} {1} to disk'.format(len(data), name))
|
||||||
|
with codecs.open(output_file, 'w', encoding='utf-8') as f:
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="ui stackable middle very relaxed page grid">
|
<div class="ui stackable middle very relaxed page grid">
|
||||||
<div class="sixteen wide center aligned centered column">
|
<div class="sixteen wide center aligned centered column">
|
||||||
<div>
|
<div>
|
||||||
<img class="logo" src="{{AppSubUrl}}/img/gitea-lg.png" />
|
<img class="logo" width="220" height="220" src="{{AssetUrlPrefix}}/img/logo.svg"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="hero">
|
<div class="hero">
|
||||||
<h1 class="ui icon header title">
|
<h1 class="ui icon header title">
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{{template "base/head" .}}
|
||||||
|
<div class="page-content user signin{{if .LinkAccountMode}} icon{{end}}">
|
||||||
|
{{template "user/auth/signin_navbar" .}}
|
||||||
|
<div class="ui middle very relaxed page grid">
|
||||||
|
<div class="ui container column fluid">
|
||||||
|
{{template "user/auth/signin_inner" .}}
|
||||||
|
To get an account (also available to external contributors), simply write to sb@m-***s.hk.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "base/footer" .}}
|
|
@ -0,0 +1,67 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
python-github-backup = pkgs.python3Packages.buildPythonApplication {
|
||||||
|
name = "python-github-backup";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "josegonzalez";
|
||||||
|
repo = "python-github-backup";
|
||||||
|
rev = "18e78a4d66120961590836e63d1fa939e4d036f3";
|
||||||
|
sha256 = "1c5qxyv322z5zkx8mxdwdqrnjgqhk00aqcgwkn53b4xkfr2idkbn";
|
||||||
|
};
|
||||||
|
patches = [ ./ghbackup-179.patch ];
|
||||||
|
propagatedBuildInputs = [ pkgs.git ];
|
||||||
|
};
|
||||||
|
token = (import /etc/nixos/secret/github_tokens.nix).backup;
|
||||||
|
makeBackup = pkgs.writeScript "make-ghbackup" ''
|
||||||
|
#!${pkgs.bash}/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
${python-github-backup}/bin/github-backup m-labs -t ${token} --all -i -o /var/lib/ghbackup/m-labs
|
||||||
|
${python-github-backup}/bin/github-backup quartiq -t ${token} --all -i -o /var/lib/ghbackup/quartiq
|
||||||
|
${python-github-backup}/bin/github-backup sinara-hw -t ${token} --all -i -o /var/lib/ghbackup/sinara-hw
|
||||||
|
|
||||||
|
echo GitHub backup done
|
||||||
|
'';
|
||||||
|
|
||||||
|
cfg = config.services.ghbackup;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.ghbackup = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable backups";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services.ghbackup = {
|
||||||
|
description = "GitHub backup";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "ghbackup";
|
||||||
|
Group = "ghbackup";
|
||||||
|
ExecStart = "${makeBackup}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.ghbackup = {
|
||||||
|
name = "ghbackup";
|
||||||
|
group = "ghbackup";
|
||||||
|
description = "GitHub backups user";
|
||||||
|
isSystemUser = true;
|
||||||
|
createHome = true;
|
||||||
|
home = "/var/lib/ghbackup";
|
||||||
|
useDefaultShell = true;
|
||||||
|
};
|
||||||
|
users.extraGroups.ghbackup = {};
|
||||||
|
|
||||||
|
systemd.timers.ghbackup = {
|
||||||
|
description = "GitHub backup";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig.OnCalendar = "daily";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
diff --git a/src/root/product-list.tt b/src/root/product-list.tt
|
||||||
|
index 4d545b3e..6049c2a6 100644
|
||||||
|
--- a/src/root/product-list.tt
|
||||||
|
+++ b/src/root/product-list.tt
|
||||||
|
@@ -162,6 +162,11 @@
|
||||||
|
<img src="[% c.uri_for("/static/images/iso.png") %]" alt="ISO" />
|
||||||
|
</td>
|
||||||
|
<td>ISO-9660 CD/DVD image</td>
|
||||||
|
+ [% CASE "msys2" %]
|
||||||
|
+ <td>
|
||||||
|
+ <img src="[% c.uri_for("/static/images/msys2.svg") %]" alt="MSYS2" width="32" height="32" />
|
||||||
|
+ </td>
|
||||||
|
+ <td>MSYS2 package</td>
|
||||||
|
[% CASE "binary-dist" %]
|
||||||
|
<td>
|
||||||
|
<img src="[% c.uri_for("/static/images/binary-dist.png") %]" alt="Binary distribution" />
|
||||||
|
diff --git a/src/root/static/images/msys2.svg b/src/root/static/images/msys2.svg
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..46baff50
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/root/static/images/msys2.svg
|
||||||
|
@@ -0,0 +1,100 @@
|
||||||
|
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
+
|
||||||
|
+<svg
|
||||||
|
+ width="36.777081mm"
|
||||||
|
+ height="36.777081mm"
|
||||||
|
+ viewBox="0 0 36.77708 36.777081"
|
||||||
|
+ version="1.1"
|
||||||
|
+ id="svg8"
|
||||||
|
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||||
|
+ sodipodi:docname="msys2_logo.svg"
|
||||||
|
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
+ xmlns="http://www.w3.org/2000/svg"
|
||||||
|
+ xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
+ xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
+ <defs
|
||||||
|
+ id="defs2" />
|
||||||
|
+ <sodipodi:namedview
|
||||||
|
+ id="base"
|
||||||
|
+ pagecolor="#ffffff"
|
||||||
|
+ bordercolor="#666666"
|
||||||
|
+ borderopacity="1.0"
|
||||||
|
+ inkscape:pageopacity="0.0"
|
||||||
|
+ inkscape:pageshadow="2"
|
||||||
|
+ inkscape:zoom="3.959798"
|
||||||
|
+ inkscape:cx="121.34457"
|
||||||
|
+ inkscape:cy="27.274119"
|
||||||
|
+ inkscape:document-units="mm"
|
||||||
|
+ inkscape:current-layer="layer1"
|
||||||
|
+ showgrid="false"
|
||||||
|
+ fit-margin-top="0"
|
||||||
|
+ fit-margin-left="0"
|
||||||
|
+ fit-margin-right="0"
|
||||||
|
+ fit-margin-bottom="0"
|
||||||
|
+ inkscape:window-width="2560"
|
||||||
|
+ inkscape:window-height="1371"
|
||||||
|
+ inkscape:window-x="0"
|
||||||
|
+ inkscape:window-y="32"
|
||||||
|
+ inkscape:window-maximized="1"
|
||||||
|
+ inkscape:pagecheckerboard="true" />
|
||||||
|
+ <metadata
|
||||||
|
+ id="metadata5">
|
||||||
|
+ <rdf:RDF>
|
||||||
|
+ <cc:Work
|
||||||
|
+ rdf:about="">
|
||||||
|
+ <dc:format>image/svg+xml</dc:format>
|
||||||
|
+ <dc:type
|
||||||
|
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
+ </cc:Work>
|
||||||
|
+ </rdf:RDF>
|
||||||
|
+ </metadata>
|
||||||
|
+ <g
|
||||||
|
+ inkscape:label="Layer 1"
|
||||||
|
+ inkscape:groupmode="layer"
|
||||||
|
+ id="layer1"
|
||||||
|
+ transform="translate(-122.70998,-169.48973)">
|
||||||
|
+ <rect
|
||||||
|
+ style="fill:#894c84;fill-opacity:1;stroke-width:0"
|
||||||
|
+ id="rect946"
|
||||||
|
+ width="36.777081"
|
||||||
|
+ height="36.777081"
|
||||||
|
+ x="122.70998"
|
||||||
|
+ y="169.48973" />
|
||||||
|
+ <path
|
||||||
|
+ style="fill:#d35e64;fill-opacity:1;stroke-width:0.133635"
|
||||||
|
+ d="m 142.72948,201.89184 c -0.32408,-0.25492 -0.35455,-0.35395 -0.3187,-1.03567 l 0.0396,-0.75379 h 0.45908 c 0.44506,0 0.45934,0.0163 0.46772,0.53453 l 0.009,0.53454 0.70308,0.0405 c 0.53885,0.031 0.7217,-0.008 0.78281,-0.16735 0.15971,-0.41619 -0.10726,-0.89779 -0.98636,-1.77935 -0.49365,-0.49504 -1.03351,-1.07713 -1.19967,-1.29353 -0.38599,-0.50269 -0.40844,-1.38334 -0.0467,-1.83013 0.23417,-0.28918 0.35554,-0.31548 1.45595,-0.31548 1.36938,0 1.67817,0.15986 1.80376,0.93383 0.11523,0.71006 -0.0673,1.20433 -0.44479,1.20433 -0.26632,0 -0.34178,-0.0979 -0.46372,-0.60136 -0.13305,-0.54937 -0.1843,-0.60509 -0.59283,-0.64461 -0.24596,-0.0238 -0.58921,-0.008 -0.76279,0.036 -0.59536,0.14942 -0.37642,0.57816 0.95393,1.86806 l 1.26953,1.23092 v 0.90178 c 0,1.37811 -0.0436,1.41874 -1.52348,1.41874 -1.06598,0 -1.29877,-0.0409 -1.60514,-0.28187 z"
|
||||||
|
+ id="path3828"
|
||||||
|
+ inkscape:connector-curvature="0" />
|
||||||
|
+ <path
|
||||||
|
+ style="fill:#d35e64;fill-opacity:1;stroke-width:0.133635"
|
||||||
|
+ d="m 148.05027,204.08841 c 0.0471,-0.28134 0.11947,-1.05275 0.16076,-1.71424 0.0703,-1.12643 0.0353,-1.35529 -0.55133,-3.60814 -0.34453,-1.32299 -0.6573,-2.54073 -0.69504,-2.70611 -0.0594,-0.26014 -0.0147,-0.30067 0.33149,-0.30067 0.22006,0 0.46737,0.081 0.54957,0.18007 0.0822,0.099 0.30254,0.86578 0.48964,1.70385 0.41743,1.86975 0.45345,1.99148 0.58914,1.99148 0.15912,0 0.35622,-0.563 0.74822,-2.13717 0.38958,-1.56447 0.48518,-1.73823 0.9564,-1.73823 0.39274,0 0.46132,-0.43504 -0.70121,4.4477 -0.46869,1.96849 -0.93011,3.74249 -1.02539,3.94223 -0.11781,0.24694 -0.29559,0.37716 -0.55559,0.40696 -0.37406,0.0429 -0.38048,0.0327 -0.29666,-0.46773 z"
|
||||||
|
+ id="path3830"
|
||||||
|
+ inkscape:connector-curvature="0" />
|
||||||
|
+ <path
|
||||||
|
+ style="fill:#d35e64;fill-opacity:1;stroke-width:0.133635"
|
||||||
|
+ d="m 155.37958,199.87478 -0.001,1.04324 c 0,0 0.0415,0.99571 -0.10812,1.13694 -0.15218,0.14363 -0.72994,0.11875 -1.5324,0.11875 -1.39413,0 -1.4684,-0.0143 -1.66996,-0.32193 -0.14282,-0.21797 -0.19775,-0.55241 -0.17012,-1.03567 0.0397,-0.69411 0.0518,-0.71373 0.43989,-0.71373 0.2965,0 0.40947,0.0687 0.43951,0.26726 0.13121,0.86712 0.13264,0.86863 0.81803,0.86863 1.33065,0 1.18669,-0.7429 -0.41998,-2.16732 -0.98712,-0.87515 -1.3045,-1.34704 -1.30163,-1.93531 0.005,-1.02426 0.44219,-1.37639 1.70885,-1.37639 1.4449,0 1.89746,0.36739 1.89746,1.54037 0,0.85 -0.80733,1.01376 -0.94108,0.1909 -0.113,-0.69515 -0.21979,-0.79583 -0.84414,-0.79583 -0.59087,0 -0.88668,0.17572 -0.88861,0.52786 -5.3e-4,0.11392 0.5857,0.76291 1.30294,1.44221"
|
||||||
|
+ id="path3832"
|
||||||
|
+ inkscape:connector-curvature="0"
|
||||||
|
+ sodipodi:nodetypes="ccssccscsccsssscc" />
|
||||||
|
+ <path
|
||||||
|
+ inkscape:connector-curvature="0"
|
||||||
|
+ id="path3826"
|
||||||
|
+ d="m 125.15872,195.23965 c -0.30592,-0.19939 -0.0836,-0.86189 0.8607,-2.56497 1.58255,-2.85415 5.22198,-10.62008 6.75854,-14.42159 0.91204,-2.25643 0.98557,-2.83541 0.41825,-3.29345 -0.30201,-0.24384 -0.34148,-0.33999 -0.22153,-0.53956 0.44174,-0.73497 2.98816,-1.05046 4.06353,-0.50346 1.1982,0.60947 1.74884,2.08184 2.47139,6.60826 0.57628,3.61017 1.00176,6.0369 1.0809,6.16495 0.21334,0.34519 0.63685,-0.49885 2.24466,-4.47355 2.25297,-5.56961 3.24559,-7.35862 4.41748,-7.9617 0.51912,-0.26714 0.89922,-0.34492 1.8995,-0.38866 1.60332,-0.0701 1.6509,-0.0327 1.64898,1.29653 -0.002,1.7237 -0.0807,1.96599 -0.76359,2.3662 -1.27599,0.74779 -2.16809,2.00702 -2.17,3.06305 -0.003,1.44987 1.07869,1.89961 2.0727,0.86208 0.20781,-0.2169 0.42671,-0.39436 0.48646,-0.39436 0.0597,0 0.10898,0.55626 0.10941,1.23612 5.2e-4,0.67987 0.0579,1.58514 0.12779,2.01171 0.14392,0.87871 0.16421,0.83597 -1.8354,3.86646 -1.11067,1.68327 -1.20806,1.92146 -0.90836,2.22164 0.18169,0.18198 0.60193,0.22609 2.48831,0.26119 l 2.26971,0.0422 0.55893,0.7403 c 0.68294,0.90455 0.72637,1.39945 0.1851,2.10909 -0.49391,0.64756 -1.48498,1.35585 -2.16303,1.54588 -0.98995,0.27744 -2.22523,-0.26803 -3.29926,-1.45686 -1.37797,-1.52525 -1.99486,-3.94203 -2.17991,-8.54021 -0.0642,-1.59436 -0.13883,-2.29481 -0.24099,-2.26075 -0.0814,0.0271 -0.99576,2.00431 -2.03189,4.39371 -3.28691,7.57995 -3.68415,8.28612 -4.54018,8.07127 -0.53578,-0.13448 -1.34919,-1.06203 -1.9102,-2.17825 -1.10951,-2.20757 -1.73511,-5.05031 -2.03723,-9.25721 -0.0871,-1.21273 -0.20858,-2.26094 -0.26996,-2.32935 -0.13588,-0.15144 -0.58442,0.82294 -2.08397,4.52711 -2.01481,4.97699 -2.79643,6.54288 -3.82036,7.65371 -0.87044,0.94432 -3.13721,1.88044 -3.68648,1.52243 z"
|
||||||
|
+ style="fill:#f9f9f9;stroke-width:0.133635" />
|
||||||
|
+ <g
|
||||||
|
+ id="g957"
|
||||||
|
+ transform="translate(36.843901,36.777081)"
|
||||||
|
+ style="fill:#999999">
|
||||||
|
+ <path
|
||||||
|
+ style="fill:#999999;fill-opacity:1;stroke-width:0.264583"
|
||||||
|
+ d="m 118.48002,154.38963 c -0.21263,-0.77937 -0.60053,-0.53763 -3.77862,-0.53763 -4.23812,0 -4.51001,0.21718 -2.65413,-2.44723 2.45703,-3.52744 3.4906,-5.92399 2.80851,-6.96499 -0.4719,-0.72022 -1.01247,-0.62449 -1.92709,0.34127 -0.84859,0.89603 -1.86894,0.41779 -1.86894,-0.95587 0,-2.01205 2.80561,-3.99992 5.38938,-3.9922 1.61399,0.005 2.43642,0.4039 3.21581,1.56044 1.12027,1.66236 0.73145,3.8557 -1.134,6.39695 -1.54383,2.10311 -0.73385,3.61259 0.95572,1.78109 1.46292,-1.68793 1.55952,0.86073 1.49098,1.70283 -0.2309,2.69619 -2.07701,4.65709 -2.49762,3.11534 z"
|
||||||
|
+ id="path961"
|
||||||
|
+ inkscape:connector-curvature="0"
|
||||||
|
+ sodipodi:nodetypes="sscccscccccs" />
|
||||||
|
+ </g>
|
||||||
|
+ </g>
|
||||||
|
+</svg>
|
|
@ -1,25 +0,0 @@
|
||||||
diff --git a/src/lib/Hydra/Schema/Builds.pm b/src/lib/Hydra/Schema/Builds.pm
|
|
||||||
index d4334300..014d07ce 100644
|
|
||||||
--- a/src/lib/Hydra/Schema/Builds.pm
|
|
||||||
+++ b/src/lib/Hydra/Schema/Builds.pm
|
|
||||||
@@ -608,6 +608,7 @@ makeQueries('', "");
|
|
||||||
makeQueries('ForProject', "and project = ?");
|
|
||||||
makeQueries('ForJobset', "and jobset_id = ?");
|
|
||||||
makeQueries('ForJob', "and jobset_id = ? and job = ?");
|
|
||||||
+makeQueries('ForJobName', "and jobset_id = (select id from jobsets j where j.name = ?) and job = ?");
|
|
||||||
|
|
||||||
|
|
||||||
my %hint = (
|
|
||||||
diff --git a/src/script/hydra-eval-jobset b/src/script/hydra-eval-jobset
|
|
||||||
index ea336bfc..2f208418 100755
|
|
||||||
--- a/src/script/hydra-eval-jobset
|
|
||||||
+++ b/src/script/hydra-eval-jobset
|
|
||||||
@@ -142,7 +142,7 @@ sub fetchInputSystemBuild {
|
|
||||||
$projectName ||= $project->name;
|
|
||||||
$jobsetName ||= $jobset->name;
|
|
||||||
|
|
||||||
- my @latestBuilds = $db->resultset('LatestSucceededForJob')
|
|
||||||
+ my @latestBuilds = $db->resultset('LatestSucceededForJobName')
|
|
||||||
->search({}, {bind => [$jobsetName, $jobName]});
|
|
||||||
|
|
||||||
my @validBuilds = ();
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
$TTL 7200
|
||||||
|
|
||||||
|
@ SOA ns.193thz.com. sb.m-labs.hk. (
|
||||||
|
2024060201
|
||||||
|
7200
|
||||||
|
3600
|
||||||
|
86400
|
||||||
|
600)
|
||||||
|
|
||||||
|
|
||||||
|
NS ns.193thz.com.
|
||||||
|
NS ns1.he.net.
|
||||||
|
|
||||||
|
A 94.190.212.123
|
||||||
|
A 202.77.7.238
|
||||||
|
AAAA 2001:470:18:390::2
|
||||||
|
MX 10 mail.m-labs.hk.
|
||||||
|
TXT "v=spf1 mx a:router.alt.m-labs.hk -all"
|
||||||
|
TXT "google-site-verification=5eIjLyhM_siRg5Fc2Z3AMSbheH0JFOn5iR3TCEXakqU"
|
||||||
|
CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1758987512"
|
||||||
|
|
||||||
|
|
||||||
|
ns A 94.190.212.123
|
||||||
|
ns AAAA 2001:470:18:390::2
|
||||||
|
|
||||||
|
mail._domainkey TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9T0cONxGXeyETE0bJ6NJVGT58fVFrfb+WxQhMskCN/mJhODyDTkRCjzE8ZnKhZGjkFZNG+PoSZlW+kpSS1LvMwzQpMRaH4zAzIexffR0l7rJR1MuQiVMsfGWpO2SLEuN74L2qH8SUBHZjrRpeSaFxwQm+prIOzZe5wTZStt/6qQIDAQAB"
|
||||||
|
_dmarc TXT "v=DMARC1; p=none"
|
||||||
|
|
||||||
|
www CNAME @
|
|
@ -0,0 +1,20 @@
|
||||||
|
$TTL 7200
|
||||||
|
|
||||||
|
@ SOA NS.XN--WBTZ5WPQAJ35CFXC.XN--J6W193G. sb.m-labs.hk. (
|
||||||
|
2024060201
|
||||||
|
7200
|
||||||
|
3600
|
||||||
|
86400
|
||||||
|
600)
|
||||||
|
|
||||||
|
|
||||||
|
NS NS.XN--WBTZ5WPQAJ35CFXC.XN--J6W193G.
|
||||||
|
NS ns1.he.net.
|
||||||
|
CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1758987512"
|
||||||
|
|
||||||
|
200 PTR router.alt.m-labs.hk.
|
||||||
|
201 PTR stewardship1.alt.m-labs.hk.
|
||||||
|
202 PTR stewardship2.alt.m-labs.hk.
|
||||||
|
203 PTR atse.alt.m-labs.hk.
|
||||||
|
204 PTR nasty-gareth.alt.m-labs.hk.
|
||||||
|
205 PTR zynq.alt.m-labs.hk.
|
|
@ -0,0 +1,30 @@
|
||||||
|
$TTL 7200
|
||||||
|
|
||||||
|
@ SOA ns.m-labs-intl.com. sb.m-labs.hk. (
|
||||||
|
2024101401
|
||||||
|
7200
|
||||||
|
3600
|
||||||
|
86400
|
||||||
|
600)
|
||||||
|
|
||||||
|
|
||||||
|
NS ns.m-labs-intl.com.
|
||||||
|
NS ns1.he.net.
|
||||||
|
NS ns1.qnetp.net.
|
||||||
|
|
||||||
|
A 5.78.86.156
|
||||||
|
AAAA 2a01:4ff:1f0:83de::1
|
||||||
|
MX 10 mail.m-labs-intl.com.
|
||||||
|
TXT "v=spf1 mx -all"
|
||||||
|
TXT "google-site-verification=BlQd5_5wWW7calKC7bZA0GdoxR8-zj4gwJEg9sGJ3l8"
|
||||||
|
CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1768317117"
|
||||||
|
|
||||||
|
ns A 94.190.212.123
|
||||||
|
ns AAAA 2001:470:18:390::2
|
||||||
|
|
||||||
|
mail A 5.78.86.156
|
||||||
|
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJVPuhSGXghO7ib8Em/Se3jfCCIJK5g4zn5pGZ3/e0I0f+zGHMuvwpjkAKf6eSmo/AAXEaco28pDi3qE5xfV512AJsORCfPoPFyNhLsj/qtri6hc5KVSWW0Ja3MSFBINDCaX78c7PXPY+3jJJGpwSBDLjdxj9AQwtfiCVlH4qE/QIDAQAB"
|
||||||
|
_dmarc TXT "v=DMARC1; p=none"
|
||||||
|
|
||||||
|
www CNAME @
|
||||||
|
hooks CNAME @
|
|
@ -0,0 +1,53 @@
|
||||||
|
$TTL 7200
|
||||||
|
|
||||||
|
@ SOA NS.XN--WBTZ5WPQAJ35CFXC.XN--J6W193G. sb.m-labs.hk. (
|
||||||
|
2024080501
|
||||||
|
7200
|
||||||
|
3600
|
||||||
|
86400
|
||||||
|
600)
|
||||||
|
|
||||||
|
|
||||||
|
NS NS.XN--WBTZ5WPQAJ35CFXC.XN--J6W193G.
|
||||||
|
NS ns1.qnetp.net.
|
||||||
|
NS ns1.he.net.
|
||||||
|
|
||||||
|
A 94.190.212.123
|
||||||
|
A 202.77.7.238
|
||||||
|
AAAA 2001:470:18:390::2
|
||||||
|
MX 10 mail.m-labs.hk.
|
||||||
|
TXT "v=spf1 mx a:router.alt.m-labs.hk -all"
|
||||||
|
TXT "google-site-verification=Tf_TEGZLG7-2BE70hMjLnzjDZ1qUeUZ6vxzbl1sagT8"
|
||||||
|
CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1758987512"
|
||||||
|
|
||||||
|
|
||||||
|
mail A 94.190.212.123
|
||||||
|
mail A 202.77.7.238
|
||||||
|
mail AAAA 2001:470:18:390::2
|
||||||
|
mail._domainkey TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl38A/Z0IInVU157qzrWgMfYm2iDHoWZsTyiiOoZdT7kHMzS/M2OMXMt7r5g1/7pCPClsGUDJvKGqVMmjJuPleMyKHwpGeT92qDNEFpt6ahneap/oYx5eBYM/vGcgmleNxyIoBHsptaZvqD4vCEFaC22f8UL5QAgQD3wCH3FwlpQIDAQAB"
|
||||||
|
_dmarc TXT "v=DMARC1; p=none"
|
||||||
|
|
||||||
|
lab CNAME @
|
||||||
|
www CNAME @
|
||||||
|
nixbld CNAME @
|
||||||
|
msys2 CNAME @
|
||||||
|
conda CNAME @
|
||||||
|
afws CNAME @
|
||||||
|
git CNAME @
|
||||||
|
chat CNAME @
|
||||||
|
hooks CNAME @
|
||||||
|
forum CNAME @
|
||||||
|
perso CNAME @
|
||||||
|
rt CNAME @
|
||||||
|
files CNAME @
|
||||||
|
docs CNAME @
|
||||||
|
|
||||||
|
rpi-1 AAAA 2001:470:f891:1:dea6:32ff:fe8a:6a93
|
||||||
|
rpi-4 AAAA 2001:470:f891:1:dea6:32ff:fe14:fce9
|
||||||
|
|
||||||
|
router.alt A 103.206.98.200
|
||||||
|
stewardship1.alt A 103.206.98.201
|
||||||
|
stewardship2.alt A 103.206.98.202
|
||||||
|
atse.alt A 103.206.98.203
|
||||||
|
nasty-gareth.alt A 103.206.98.204
|
||||||
|
zynq.alt A 103.206.98.205
|
|
@ -0,0 +1,28 @@
|
||||||
|
$TTL 7200
|
||||||
|
|
||||||
|
@ SOA ns1.m-labs.ph. sb.m-labs.hk. (
|
||||||
|
2024060201
|
||||||
|
7200
|
||||||
|
3600
|
||||||
|
86400
|
||||||
|
600)
|
||||||
|
|
||||||
|
|
||||||
|
NS ns1.m-labs.ph.
|
||||||
|
NS ns1.he.net.
|
||||||
|
|
||||||
|
A 94.190.212.123
|
||||||
|
A 202.77.7.238
|
||||||
|
AAAA 2001:470:18:390::2
|
||||||
|
MX 10 mail.m-labs.hk.
|
||||||
|
TXT "v=spf1 mx a:router.alt.m-labs.hk -all"
|
||||||
|
TXT "google-site-verification=g2k8M1fhbYOPs4C37SeGCfNlD6paWcexamji1DXrp0o"
|
||||||
|
CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1758987512"
|
||||||
|
|
||||||
|
ns1 A 94.190.212.123
|
||||||
|
ns1 AAAA 2001:470:18:390::2
|
||||||
|
|
||||||
|
mail._domainkey TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPUlkoA4Gucsin6P5LSohSOpPbpOELkbKDz9MmB4Zzj4QdcQNtMzU3Uis8WZwVXknQ/6URoDdTa4aR8+PwMi5fjKpLM8ZAnnHJHYebZPDRq6lQo3VGdaCu9NhdjYwFhvK9VRyhwI9i7DUptdLsu/OzbgTlCdWQTOr+MFEkYwmxLQIDAQAB"
|
||||||
|
_dmarc TXT "v=DMARC1; p=none"
|
||||||
|
|
||||||
|
www CNAME @
|
|
@ -0,0 +1,23 @@
|
||||||
|
$TTL 7200
|
||||||
|
|
||||||
|
@ SOA ns.malloctech.fr. sb.m-labs.hk. (
|
||||||
|
2024060201
|
||||||
|
7200
|
||||||
|
3600
|
||||||
|
86400
|
||||||
|
600)
|
||||||
|
|
||||||
|
|
||||||
|
NS ns.malloctech.fr.
|
||||||
|
NS ns1.he.net.
|
||||||
|
|
||||||
|
MX 10 mail.m-labs.hk.
|
||||||
|
TXT "v=spf1 mx a:router.alt.m-labs.hk -all"
|
||||||
|
TXT "google-site-verification=LALF-fafTnmkL-18m3CzwFjSwEV1C7NeKexiNfMYsOw"
|
||||||
|
CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1758987512"
|
||||||
|
|
||||||
|
ns A 94.190.212.123
|
||||||
|
ns AAAA 2001:470:18:390::2
|
||||||
|
|
||||||
|
mail._domainkey TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+Op2B9cdVxwyweChOBJtk4LGkLUfxunI3a7sSL0aVnntfPWkKgY7zTL8iOJaqdt/DkkvOz++HEsn3AzleXsdibaTC9x6kgrMVgkrsYOKA4bWDLJiUfgq7vvRMdkw6rOqlJp9+faXKIKwtMG9Ckd1+rHBsaFwe7EE0coLbhGZaQQIDAQAB"
|
||||||
|
_dmarc TXT "v=DMARC1; p=none"
|
|
@ -1,84 +0,0 @@
|
||||||
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
|
|
||||||
index 53a0958a..16a98aec 100644
|
|
||||||
--- a/src/libstore/build.cc
|
|
||||||
+++ b/src/libstore/build.cc
|
|
||||||
@@ -809,9 +809,16 @@ private:
|
|
||||||
/* Whether this is a fixed-output derivation. */
|
|
||||||
bool fixedOutput;
|
|
||||||
|
|
||||||
+ bool networked;
|
|
||||||
+
|
|
||||||
/* Whether to run the build in a private network namespace. */
|
|
||||||
bool privateNetwork = false;
|
|
||||||
|
|
||||||
+ bool allowNetwork()
|
|
||||||
+ {
|
|
||||||
+ return fixedOutput || networked;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
typedef void (DerivationGoal::*GoalState)();
|
|
||||||
GoalState state;
|
|
||||||
|
|
||||||
@@ -1179,6 +1186,8 @@ void DerivationGoal::haveDerivation()
|
|
||||||
{
|
|
||||||
trace("have derivation");
|
|
||||||
|
|
||||||
+ fixedOutput = drv->isFixedOutput();
|
|
||||||
+
|
|
||||||
retrySubstitution = false;
|
|
||||||
|
|
||||||
for (auto & i : drv->outputs)
|
|
||||||
@@ -1195,6 +1204,8 @@ void DerivationGoal::haveDerivation()
|
|
||||||
|
|
||||||
parsedDrv = std::make_unique<ParsedDerivation>(drvPath, *drv);
|
|
||||||
|
|
||||||
+ networked = parsedDrv->getBoolAttr("__networked");
|
|
||||||
+
|
|
||||||
/* We are first going to try to create the invalid output paths
|
|
||||||
through substitutes. If that doesn't work, we'll build
|
|
||||||
them. */
|
|
||||||
@@ -1987,7 +1998,7 @@ void DerivationGoal::startBuilder()
|
|
||||||
else if (settings.sandboxMode == smDisabled)
|
|
||||||
useChroot = false;
|
|
||||||
else if (settings.sandboxMode == smRelaxed)
|
|
||||||
- useChroot = !fixedOutput && !noChroot;
|
|
||||||
+ useChroot = !allowNetwork() && !noChroot;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (worker.store.storeDir != worker.store.realStoreDir) {
|
|
||||||
@@ -2153,7 +2164,7 @@ void DerivationGoal::startBuilder()
|
|
||||||
"nogroup:x:65534:\n") % sandboxGid).str());
|
|
||||||
|
|
||||||
/* Create /etc/hosts with localhost entry. */
|
|
||||||
- if (!fixedOutput)
|
|
||||||
+ if (!allowNetwork())
|
|
||||||
writeFile(chrootRootDir + "/etc/hosts", "127.0.0.1 localhost\n::1 localhost\n");
|
|
||||||
|
|
||||||
/* Make the closure of the inputs available in the chroot,
|
|
||||||
@@ -2361,7 +2372,7 @@ void DerivationGoal::startBuilder()
|
|
||||||
us.
|
|
||||||
*/
|
|
||||||
|
|
||||||
- if (!fixedOutput)
|
|
||||||
+ if (!allowNetwork())
|
|
||||||
privateNetwork = true;
|
|
||||||
|
|
||||||
userNamespaceSync.create();
|
|
||||||
@@ -2573,7 +2584,7 @@ void DerivationGoal::initEnv()
|
|
||||||
to the builder is generally impure, but the output of
|
|
||||||
fixed-output derivations is by definition pure (since we
|
|
||||||
already know the cryptographic hash of the output). */
|
|
||||||
- if (fixedOutput) {
|
|
||||||
+ if (allowNetwork()) {
|
|
||||||
for (auto & i : parsedDrv->getStringsAttr("impureEnvVars").value_or(Strings()))
|
|
||||||
env[i] = getEnv(i).value_or("");
|
|
||||||
}
|
|
||||||
@@ -3184,7 +3195,7 @@ void DerivationGoal::runChild()
|
|
||||||
/* Fixed-output derivations typically need to access the
|
|
||||||
network, so give them access to /etc/resolv.conf and so
|
|
||||||
on. */
|
|
||||||
- if (fixedOutput) {
|
|
||||||
+ if (allowNetwork()) {
|
|
||||||
ss.push_back("/etc/resolv.conf");
|
|
||||||
|
|
||||||
// Only use nss functions to resolve hosts and
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
|
||||||
|
index 763045a80..d7c5cc82e 100644
|
||||||
|
--- a/src/libstore/build/local-derivation-goal.cc
|
||||||
|
+++ b/src/libstore/build/local-derivation-goal.cc
|
||||||
|
@@ -190,6 +190,8 @@ void LocalDerivationGoal::tryLocalBuild()
|
||||||
|
|
||||||
|
assert(derivationType);
|
||||||
|
|
||||||
|
+ networked = parsedDrv->getBoolAttr("__networked");
|
||||||
|
+
|
||||||
|
/* Are we doing a chroot build? */
|
||||||
|
{
|
||||||
|
auto noChroot = parsedDrv->getBoolAttr("__noChroot");
|
||||||
|
@@ -207,7 +209,7 @@ void LocalDerivationGoal::tryLocalBuild()
|
||||||
|
else if (settings.sandboxMode == smDisabled)
|
||||||
|
useChroot = false;
|
||||||
|
else if (settings.sandboxMode == smRelaxed)
|
||||||
|
- useChroot = derivationType->isSandboxed() && !noChroot;
|
||||||
|
+ useChroot = !networked && derivationType->isSandboxed() && !noChroot;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto & localStore = getLocalStore();
|
||||||
|
@@ -717,7 +719,7 @@ void LocalDerivationGoal::startBuilder()
|
||||||
|
"nogroup:x:65534:\n", sandboxGid()));
|
||||||
|
|
||||||
|
/* Create /etc/hosts with localhost entry. */
|
||||||
|
- if (derivationType->isSandboxed())
|
||||||
|
+ if (!networked && derivationType->isSandboxed())
|
||||||
|
writeFile(chrootRootDir + "/etc/hosts", "127.0.0.1 localhost\n::1 localhost\n");
|
||||||
|
|
||||||
|
/* Make the closure of the inputs available in the chroot,
|
||||||
|
@@ -921,7 +923,7 @@ void LocalDerivationGoal::startBuilder()
|
||||||
|
us.
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (derivationType->isSandboxed())
|
||||||
|
+ if (!networked && derivationType->isSandboxed())
|
||||||
|
privateNetwork = true;
|
||||||
|
|
||||||
|
userNamespaceSync.create();
|
||||||
|
@@ -1160,7 +1162,7 @@ void LocalDerivationGoal::initEnv()
|
||||||
|
to the builder is generally impure, but the output of
|
||||||
|
fixed-output derivations is by definition pure (since we
|
||||||
|
already know the cryptographic hash of the output). */
|
||||||
|
- if (!derivationType->isSandboxed()) {
|
||||||
|
+ if (networked || !derivationType->isSandboxed()) {
|
||||||
|
for (auto & i : parsedDrv->getStringsAttr("impureEnvVars").value_or(Strings()))
|
||||||
|
env[i] = getEnv(i).value_or("");
|
||||||
|
}
|
||||||
|
@@ -1829,7 +1831,7 @@ void LocalDerivationGoal::runChild()
|
||||||
|
/* Fixed-output derivations typically need to access the
|
||||||
|
network, so give them access to /etc/resolv.conf and so
|
||||||
|
on. */
|
||||||
|
- if (!derivationType->isSandboxed()) {
|
||||||
|
+ if (networked || !derivationType->isSandboxed()) {
|
||||||
|
// Only use nss functions to resolve hosts and
|
||||||
|
// services. Don’t use it for anything else that may
|
||||||
|
// be configured for this system. This limits the
|
||||||
|
@@ -2071,7 +2073,7 @@ void LocalDerivationGoal::runChild()
|
||||||
|
#include "sandbox-defaults.sb"
|
||||||
|
;
|
||||||
|
|
||||||
|
- if (!derivationType->isSandboxed())
|
||||||
|
+ if (networked || !derivationType->isSandboxed())
|
||||||
|
sandboxProfile +=
|
||||||
|
#include "sandbox-network.sb"
|
||||||
|
;
|
||||||
|
diff --git a/src/libstore/build/local-derivation-goal.hh b/src/libstore/build/local-derivation-goal.hh
|
||||||
|
index 86b86c01e..95b03aae8 100644
|
||||||
|
--- a/src/libstore/build/local-derivation-goal.hh
|
||||||
|
+++ b/src/libstore/build/local-derivation-goal.hh
|
||||||
|
@@ -82,6 +82,8 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||||
|
*/
|
||||||
|
Path chrootRootDir;
|
||||||
|
|
||||||
|
+ bool networked;
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* RAII object to delete the chroot directory.
|
||||||
|
*/
|
|
@ -14,6 +14,13 @@ from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
mail_password_file = getenv("FLASK_MAIL_PASSWORD_FILE")
|
||||||
|
if mail_password_file is not None:
|
||||||
|
with open(mail_password_file, "r") as f:
|
||||||
|
mail_password = f.read().strip()
|
||||||
|
else:
|
||||||
|
mail_password = None
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.update(
|
app.config.update(
|
||||||
DEBUG=getenv("FLASK_DEBUG") == "True",
|
DEBUG=getenv("FLASK_DEBUG") == "True",
|
||||||
|
@ -22,7 +29,7 @@ app.config.update(
|
||||||
MAIL_USE_SSL=getenv("FLASK_MAIL_USE_SSL"),
|
MAIL_USE_SSL=getenv("FLASK_MAIL_USE_SSL"),
|
||||||
MAIL_DEBUG=False,
|
MAIL_DEBUG=False,
|
||||||
MAIL_USERNAME=getenv("FLASK_MAIL_USERNAME"),
|
MAIL_USERNAME=getenv("FLASK_MAIL_USERNAME"),
|
||||||
MAIL_PASSWORD=getenv("FLASK_MAIL_PASSWORD"),
|
MAIL_PASSWORD=mail_password,
|
||||||
MAIL_RECIPIENT=getenv("FLASK_MAIL_RECIPIENT"),
|
MAIL_RECIPIENT=getenv("FLASK_MAIL_RECIPIENT"),
|
||||||
MAIL_SENDER=getenv("FLASK_MAIL_SENDER")
|
MAIL_SENDER=getenv("FLASK_MAIL_SENDER")
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,13 +7,13 @@ in {
|
||||||
pythonPackages = self: [ pkg ];
|
pythonPackages = self: [ pkg ];
|
||||||
module = "rfq:app";
|
module = "rfq:app";
|
||||||
env = [
|
env = [
|
||||||
"FLASK_MAIL_SERVER=ssl.serverraum.org"
|
"FLASK_MAIL_SERVER=mail.m-labs.hk"
|
||||||
"FLASK_MAIL_PORT=465"
|
"FLASK_MAIL_PORT=465"
|
||||||
"FLASK_MAIL_USE_SSL=True"
|
"FLASK_MAIL_USE_SSL=True"
|
||||||
"FLASK_MAIL_USERNAME=sales@m-labs.hk"
|
"FLASK_MAIL_USERNAME=sysop@m-labs.hk"
|
||||||
"FLASK_MAIL_PASSWORD=${import /etc/nixos/secret/sales_password.nix}"
|
"FLASK_MAIL_PASSWORD_FILE=/etc/nixos/secret/rfqpassword"
|
||||||
"FLASK_MAIL_RECIPIENT=sales@m-labs.hk"
|
"FLASK_MAIL_RECIPIENT=sales@m-labs.hk"
|
||||||
"FLASK_MAIL_SENDER=sales@m-labs.hk"
|
"FLASK_MAIL_SENDER=sysop@m-labs.hk"
|
||||||
];
|
];
|
||||||
socket = "${config.services.uwsgi.runDir}/uwsgi-rfq.sock";
|
socket = "${config.services.uwsgi.runDir}/uwsgi-rfq.sock";
|
||||||
# allow access from nginx
|
# allow access from nginx
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
diff '--color=auto' -Naur rt-5.0.1/lib/RT/Interface/Web.pm rtpatched/lib/RT/Interface/Web.pm
|
||||||
|
--- rt-5.0.1/lib/RT/Interface/Web.pm 1970-01-01 08:00:01.000000000 +0800
|
||||||
|
+++ rtpatched/lib/RT/Interface/Web.pm 2021-08-12 13:34:08.870669968 +0800
|
||||||
|
@@ -948,6 +948,7 @@
|
||||||
|
-path => RT->Config->Get('WebPath'),
|
||||||
|
-secure => ( RT->Config->Get('WebSecureCookies') ? 1 : 0 ),
|
||||||
|
-httponly => ( RT->Config->Get('WebHttpOnlyCookies') ? 1 : 0 ),
|
||||||
|
+ -expires => '+6M',
|
||||||
|
);
|
||||||
|
|
||||||
|
$HTML::Mason::Commands::r->err_headers_out->{'Set-Cookie'} = $cookie->as_string;
|
|
@ -0,0 +1,298 @@
|
||||||
|
# based on https://gist.github.com/ajs124/ff04ab14435908d914cf5cedbc56a52e
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.services.rt;
|
||||||
|
|
||||||
|
configFile = pkgs.writeTextFile {
|
||||||
|
name = "RT_SiteConfig.pm";
|
||||||
|
text = ''
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
# System (Base configuration)
|
||||||
|
Set($rtname, '${cfg.rtName}'); # Changing this will break responses to existing tickets
|
||||||
|
Set($Organization, '${cfg.organization}'); # Changing this will break all existing tickets
|
||||||
|
Set($CorrespondAddress, '${cfg.correspondAddress}');
|
||||||
|
Set($CommentAddress, '${cfg.commentAddress}');
|
||||||
|
Set($WebDomain, '${cfg.domain}');
|
||||||
|
Set($Timezone, '${cfg.timeZone}');
|
||||||
|
|
||||||
|
Set($DatabaseType, 'Pg');
|
||||||
|
Set($DatabaseHost, '/run/postgresql');
|
||||||
|
Set($DatabaseUser, 'rt');
|
||||||
|
Set($DatabaseName, 'rt5');
|
||||||
|
|
||||||
|
# System (Logging)
|
||||||
|
Set($LogToSTDERR, undef); # Don't log twice
|
||||||
|
|
||||||
|
# System (Incoming mail gateway)
|
||||||
|
Set($OwnerEmail, '${cfg.ownerEmail}');
|
||||||
|
Set($MaxAttachmentSize, 15360000);
|
||||||
|
Set($CheckMoreMSMailHeaders, 1);
|
||||||
|
Set($RTAddressRegexp, '^(helpdesk)\@(m-labs.hk|m-labs-intl.com)$');
|
||||||
|
Set($LoopsToRTOwner, 0);
|
||||||
|
|
||||||
|
# System (Outgoing mail)
|
||||||
|
Set($SetOutgoingMailFrom, 'helpdesk@m-labs.hk');
|
||||||
|
|
||||||
|
# System (Sendmail configuration)
|
||||||
|
Set($SendmailPath, '${cfg.sendmailPath}');
|
||||||
|
Set($SendmailArguments, '${concatStringsSep " " cfg.sendmailArguments}');
|
||||||
|
|
||||||
|
# System (Application logic)
|
||||||
|
Set($ParseNewMessageForTicketCcs, 1);
|
||||||
|
|
||||||
|
# System (Extra Security)
|
||||||
|
Set($RestrictLoginReferrer, 1);
|
||||||
|
|
||||||
|
# System (Date and time handling)
|
||||||
|
Set($DefaultTimeUnitsToHours, 1);
|
||||||
|
Set($TimeInICal, 1);
|
||||||
|
Set($DateTimeFormat, 'RFC2822');
|
||||||
|
|
||||||
|
# System (Authorization and user configuration)
|
||||||
|
Set($AutoLogoff, 262800); # 6 months
|
||||||
|
Set($WebSecureCookies, 1);
|
||||||
|
|
||||||
|
# Web Interface (Base configuration)
|
||||||
|
Set($CanonicalizeRedirectURLs, 1);
|
||||||
|
Set($CanonicalizeURLsInFeeds, 1);
|
||||||
|
Set($WebBaseURL, '${cfg.baseUrl}');
|
||||||
|
Set($LogoLinkURL, '${cfg.baseUrl}');
|
||||||
|
|
||||||
|
# Web Interface (Home page)
|
||||||
|
Set($DefaultSummaryRows, 50);
|
||||||
|
|
||||||
|
# Web Interface (Ticket search)
|
||||||
|
Set($DefaultSearchResultOrder, 'DESC'); # Display newer tickets first
|
||||||
|
Set($SearchResultsAutoRedirect, 1); # Don't show result list when there is only one match
|
||||||
|
Set(%FullTextSearch,
|
||||||
|
Enable => 1,
|
||||||
|
Indexed => 1,
|
||||||
|
Column => 'ContentIndex',
|
||||||
|
Table => 'AttachmentsIndex',
|
||||||
|
);
|
||||||
|
|
||||||
|
# Web Interface (Ticket options)
|
||||||
|
Set($ShowMoreAboutPrivilegedUsers, 1);
|
||||||
|
Set($MoreAboutRequestorGroupsLimit, undef);
|
||||||
|
Set($HideUnsetFieldsOnDisplay, 1);
|
||||||
|
|
||||||
|
# Web Interface (Articles)
|
||||||
|
Set($ArticleOnTicketCreate, 0);
|
||||||
|
|
||||||
|
# Web Interface (Message box properties)
|
||||||
|
Set($MessageBoxRichText, 0);
|
||||||
|
Set($MessageBoxIncludeSignatureOnComment, 0);
|
||||||
|
|
||||||
|
# Web Interface (Transaction display)
|
||||||
|
Set($MaxInlineBody, 0);
|
||||||
|
Set($SuppressInlineTextFiles, 1);
|
||||||
|
|
||||||
|
# Web Interface (Administrative interface)
|
||||||
|
Set($ShowRTPortal, 0);
|
||||||
|
Set($ShowEditSsytemConfig, 0);
|
||||||
|
|
||||||
|
# Features (External storage)
|
||||||
|
Set(%ExternalStorage,
|
||||||
|
Type => 'Disk',
|
||||||
|
Path => '/var/lib/rt/attachments',
|
||||||
|
);
|
||||||
|
Set($ExternalStorageCutoffSize, 0);
|
||||||
|
|
||||||
|
# Features (Cryptography)
|
||||||
|
Set(%Crypt, RejectOnMissingPrivateKey => 0, RejectOnBadData => 0, AllowEncryptDataInDB => 0);
|
||||||
|
Set(%SMIME, Enable => 1, Keyring => '${pkgs.cacert}/etc/ssl/certs/');
|
||||||
|
Set(%GnuPG, Enable => 1);
|
||||||
|
Set(%GnuPGOptions,
|
||||||
|
'keyserver' => 'hkp://keys.openpgp.org',
|
||||||
|
'always-trust' => undef,
|
||||||
|
'auto-key-locate' => 'keyserver',
|
||||||
|
'keyserver-options' => 'auto-key-retrieve'
|
||||||
|
);
|
||||||
|
|
||||||
|
${cfg.extraConfig}
|
||||||
|
|
||||||
|
1;
|
||||||
|
'';
|
||||||
|
checkPhase = ''
|
||||||
|
${pkgs.perl}/bin/perl -c $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options.services.rt = with types; {
|
||||||
|
|
||||||
|
enable = mkEnableOption "rt system";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
description = "Package to use";
|
||||||
|
default = pkgs.rt;
|
||||||
|
defaultText = "pkgs.rt";
|
||||||
|
type = package;
|
||||||
|
};
|
||||||
|
|
||||||
|
baseUrl = mkOption {
|
||||||
|
description = "Base URL for web interface";
|
||||||
|
default = "https://${cfg.domain}";
|
||||||
|
defaultText = "https://\${cfg.domain}";
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
|
||||||
|
commentAddress = mkOption {
|
||||||
|
description = "Default address from/to which comments are sent";
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
|
||||||
|
correspondAddress = mkOption {
|
||||||
|
description = "Default address from/to which correspondences are sent";
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
|
||||||
|
domain = mkOption {
|
||||||
|
description = "Which domain RT is running on";
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
|
||||||
|
ownerEmail = mkOption {
|
||||||
|
description = "Address of a human who manages RT. RT will send errors generated by the mail gateway to this address; it will also be displayed as the contact person on the RT's login page.";
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
description = "Which port rt-server should listen on";
|
||||||
|
type = port;
|
||||||
|
default = 4201;
|
||||||
|
};
|
||||||
|
|
||||||
|
sendmailPath = mkOption {
|
||||||
|
description = "Sendmail binary used to send... mail";
|
||||||
|
default = "${pkgs.msmtp}/bin/sendmail";
|
||||||
|
defaultText = "\${pkgs.msmtp}/bin/sendmail";
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
|
||||||
|
sendmailArguments = mkOption {
|
||||||
|
description = "Arguments to call sendmailPath with";
|
||||||
|
default = [ ];
|
||||||
|
type = listOf (oneOf [ str path ]);
|
||||||
|
};
|
||||||
|
|
||||||
|
timeZone = mkOption {
|
||||||
|
description = "Used to convert times entered by users into GMT, as they are stored in the database, and back again; users can override this";
|
||||||
|
type = str;
|
||||||
|
default = config.time.timeZone;
|
||||||
|
defaultText = "[time.timeZone]";
|
||||||
|
};
|
||||||
|
|
||||||
|
rtName = mkOption {
|
||||||
|
description = "Name of this RT instance";
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
|
||||||
|
organization = mkOption {
|
||||||
|
description = "Name of the organization of this instance";
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
description = "Verbatim config to append to generated on";
|
||||||
|
type = lines;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
components = [
|
||||||
|
"rt-clean-sessions"
|
||||||
|
"rt-email-dashboards"
|
||||||
|
"rt-email-digest-daily"
|
||||||
|
"rt-email-digest-weekly"
|
||||||
|
"rt-externalize-attachments"
|
||||||
|
"rt-fulltext-indexer"
|
||||||
|
"rt-validator"
|
||||||
|
];
|
||||||
|
|
||||||
|
mkTimer = name: {
|
||||||
|
"${name}" = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig.Unit = [ "${name}.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkService = name: extraArgs: {
|
||||||
|
"${name}" = {
|
||||||
|
stopIfChanged = false;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = if extraArgs == ""
|
||||||
|
then "${cfg.package}/bin/${name}"
|
||||||
|
else mkForce "${cfg.package}/bin/${name} ${extraArgs}";
|
||||||
|
User = "rt";
|
||||||
|
Group = "rt";
|
||||||
|
|
||||||
|
PrivateNetwork = false;
|
||||||
|
MemoryDenyWriteExecute = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
RT_SITE_CONFIG = configFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
path = with pkgs; [
|
||||||
|
w3m
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in (mkIf cfg.enable {
|
||||||
|
systemd.services = mkMerge ((map (c: mkService c "") components) ++ [
|
||||||
|
(mkService "rt-server" "--port ${toString cfg.port} --server Starman")
|
||||||
|
(mkService "rt-clean-sessions" "--skip-user")
|
||||||
|
(mkService "rt-fulltext-indexer" "--limit 500000")
|
||||||
|
(mkService "rt-validator" "--check")
|
||||||
|
{
|
||||||
|
rt-server = {
|
||||||
|
serviceConfig = {
|
||||||
|
StateDirectory = [ "rt/" "rt/attachments/" "rt/shredder/" "rt/smime/" ];
|
||||||
|
RuntimeDirectory = [ "rt/" "rt/mason_data/" ];
|
||||||
|
LogsDirectory = "rt/";
|
||||||
|
};
|
||||||
|
|
||||||
|
after = [ "postgresql.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
rt-externalize-attachments = {
|
||||||
|
serviceConfig.StateDirectory = "rt/attachments/";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
{ rt-email-digest-daily.serviceConfig.ExecStart = mkForce "${cfg.package}/bin/rt-email-digest -m daily"; }
|
||||||
|
{ rt-email-digest-weekly.serviceConfig.ExecStart = mkForce "${cfg.package}/bin/rt-email-digest -m weekly"; }
|
||||||
|
]);
|
||||||
|
|
||||||
|
systemd.timers = mkMerge ((map mkTimer components) ++ [
|
||||||
|
{
|
||||||
|
rt-clean-sessions.timerConfig.OnCalendar = "daily";
|
||||||
|
rt-email-dashboards.timerConfig.OnCalendar = "hourly";
|
||||||
|
rt-email-digest-daily.timerConfig.OnCalendar = "daily";
|
||||||
|
rt-email-digest-weekly.timerConfig.OnCalendar = "weekly";
|
||||||
|
rt-externalize-attachments.timerConfig.OnCalendar = "01:00";
|
||||||
|
rt-fulltext-indexer.timerConfig.OnCalendar = "02:00";
|
||||||
|
rt-validator.timerConfig.OnCalendar = "*-*-01 03:00:00";
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
users.users.rt = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "rt";
|
||||||
|
};
|
||||||
|
users.groups.rt = {};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /var/lib/secrets/rt 0500 rt rt -"
|
||||||
|
"d /var/lib/rt/gpg 0700 rt rt -"
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
-rw------- 1 root root backup-passphrase
|
-rw------- 1 root root backup-passphrase
|
||||||
-rw------- 1 root root email_accounts.nix
|
-rw------- 1 root root email_accounts.nix
|
||||||
-rw------- 1 homu homu homu.toml
|
-rw------- 1 root root gitea_tokens.nix
|
||||||
|
-rw------- 1 root root github_tokens.nix
|
||||||
-rw-rw---- 1 gitea gitea mailerpassword
|
-rw-rw---- 1 gitea gitea mailerpassword
|
||||||
-rw------- 1 matterbridge matterbridge matterbridge.toml
|
-rw------- 1 matterbridge matterbridge matterbridge.toml
|
||||||
-rw------- 1 uwsgi uwsgi mattermost-github-integration.py
|
-rw------- 1 uwsgi uwsgi mattermost-github-integration.py
|
||||||
-rw------- 1 nginx nginx muninpasswd
|
-rw------- 1 nginx nginx muninpasswd
|
||||||
-rw-rw---- 1 hydra hydra nixbld.m-labs.hk-1
|
-rw-rw---- 1 hydra hydra nixbld.m-labs.hk-1
|
||||||
-rw-rw---- 1 hydra hydra nix_id_rsa
|
|
||||||
-rw------- 1 root root rclone.conf
|
|
||||||
-rw------- 1 root root wifi_password.nix
|
-rw------- 1 root root wifi_password.nix
|
||||||
|
-rw------- 1 sb users wifi_ext_password.nix
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "ahci" "nvme" "usbhid" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/89463254-b38d-45db-92b6-0f7d92a44f47";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/F84B-ACC5";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.enp86s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "23.11";
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
avscan = pkgs.writeScript "avscan" ''
|
||||||
|
#!${pkgs.bash}/bin/bash
|
||||||
|
|
||||||
|
for user in $(cut -d":" -f1 /etc/passwd); do
|
||||||
|
if [ -d "/home/$user" ]; then
|
||||||
|
nice -15 ${pkgs.sudo}/bin/sudo -u $user ${pkgs.clamav}/bin/clamscan --recursive --quiet --infected /home/$user
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
cfg = config.services.avscan;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.avscan = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable antivirus scan";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.clamav.updater.enable = true;
|
||||||
|
services.clamav.updater.interval = "daily";
|
||||||
|
services.clamav.updater.frequency = 1;
|
||||||
|
|
||||||
|
systemd.services.avscan = {
|
||||||
|
description = "Antivirus scan";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "root";
|
||||||
|
Group = "root";
|
||||||
|
ExecStart = "${avscan}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.avscan = {
|
||||||
|
description = "Antivirus scan";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig.OnCalendar = "Mon *-*-* 13:00:00";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,6 +1,3 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -21,13 +18,18 @@
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-uuid/060C-8772";
|
{ device = "/dev/disk/by-uuid/060C-8772";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
|
|
||||||
nix.maxJobs = lib.mkDefault 16;
|
nix.settings.max-jobs = lib.mkDefault 16;
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "19.03";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports =
|
|
||||||
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "ata_generic" "uhci_hcd" "ehci_pci" "ahci" "usb_storage" "usbhid" "floppy" "sd_mod" "sr_mod" ];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
fileSystems."/" =
|
|
||||||
{ device = "/dev/disk/by-uuid/35d9c50c-e479-43a9-8324-b8ded5b71844";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices =
|
|
||||||
[ { device = "/dev/disk/by-uuid/d8480389-c558-4c46-a58f-00207315dbdd"; }
|
|
||||||
];
|
|
||||||
|
|
||||||
nix.maxJobs = lib.mkDefault 2;
|
|
||||||
|
|
||||||
boot.loader.grub.enable = true;
|
|
||||||
boot.loader.grub.version = 2;
|
|
||||||
boot.loader.grub.device = "/dev/sda";
|
|
||||||
|
|
||||||
services.xserver.videoDrivers = ["intel"];
|
|
||||||
}
|
|
|
@ -1,11 +1,17 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
root = {
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF/YybP+fQ0J+bNqM5Vgx5vDmVqVWsgUdF1moUxghv7d73GZAFaM6IFBdrXTAa33AwnWwDPMrTgP1V6SXBkb3ciJo/lD1urJGbydbSI5Ksq9d59wvOeANvyWYrQw6+eqTQ=="
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMALVC8RDTHec+PC8y1s3tcpUAODgq6DEzQdHDf/cyvDMfmCaPiMxfIdmkns5lMa03hymIfSmLUF0jFFDc7biRp7uf9AAXNsrTmplHii0l0McuOOZGlSdZM4eL817P7UwJqFMxJyFXDjkubhQiX6kp25Kfuj/zLnupRCaiDvE7ho/xay6Jrv0XLz935TPDwkc7W1asLIvsZLheB+sRz9SMOb9gtrvk5WXZl5JTOFOLu+JaRwQLHL/xdcHJTOod7tqHYfpoC5JHrEwKzbhTOwxZBQBfTQjQktKENQtBxXHTe71rUEWfEZQGg60/BC4BrRmh4qJjlJu3v4VIhC7SSHn1"
|
||||||
|
];
|
||||||
|
};
|
||||||
sb = {
|
sb = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = ["wheel" "plugdev" "dialout"];
|
extraGroups = ["wheel" "plugdev" "dialout" "libvirtd"];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyPk5WyFoWSvF4ozehxcVBoZ+UHgrI7VW/OoQfFFwIQe0qvetUZBMZwR2FwkLPAMZV8zz1v4EfncudEkVghy4P+/YVLlDjqDq9zwZnh8Nd/ifu84wmcNWHT2UcqnhjniCdshL8a44memzABnxfLLv+sXhP2x32cJAamo5y6fukr2qLp2jbXzR+3sv3klE0ruUXis/BR1lLqNJEYP8jB6fLn2sLKinnZPfn6DwVOk10mGeQsdME/eGl3phpjhODH9JW5V2V5nJBbC0rBnq+78dyArKVqjPSmIcSy72DEIpTctnMEN1W34BGrnsDd5Xd/DKxKxHKTMCHtZRwLC2X0NWN"
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF/YybP+fQ0J+bNqM5Vgx5vDmVqVWsgUdF1moUxghv7d73GZAFaM6IFBdrXTAa33AwnWwDPMrTgP1V6SXBkb3ciJo/lD1urJGbydbSI5Ksq9d59wvOeANvyWYrQw6+eqTQ=="
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMALVC8RDTHec+PC8y1s3tcpUAODgq6DEzQdHDf/cyvDMfmCaPiMxfIdmkns5lMa03hymIfSmLUF0jFFDc7biRp7uf9AAXNsrTmplHii0l0McuOOZGlSdZM4eL817P7UwJqFMxJyFXDjkubhQiX6kp25Kfuj/zLnupRCaiDvE7ho/xay6Jrv0XLz935TPDwkc7W1asLIvsZLheB+sRz9SMOb9gtrvk5WXZl5JTOFOLu+JaRwQLHL/xdcHJTOod7tqHYfpoC5JHrEwKzbhTOwxZBQBfTQjQktKENQtBxXHTe71rUEWfEZQGg60/BC4BrRmh4qJjlJu3v4VIhC7SSHn1"
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMALVC8RDTHec+PC8y1s3tcpUAODgq6DEzQdHDf/cyvDMfmCaPiMxfIdmkns5lMa03hymIfSmLUF0jFFDc7biRp7uf9AAXNsrTmplHii0l0McuOOZGlSdZM4eL817P7UwJqFMxJyFXDjkubhQiX6kp25Kfuj/zLnupRCaiDvE7ho/xay6Jrv0XLz935TPDwkc7W1asLIvsZLheB+sRz9SMOb9gtrvk5WXZl5JTOFOLu+JaRwQLHL/xdcHJTOod7tqHYfpoC5JHrEwKzbhTOwxZBQBfTQjQktKENQtBxXHTe71rUEWfEZQGg60/BC4BrRmh4qJjlJu3v4VIhC7SSHn1"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -19,65 +25,98 @@
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMUaB2G1jexxfkdlly3fdWslH54/s/bOuvk9AxqpjtAY robert-jordens-ed25519"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMUaB2G1jexxfkdlly3fdWslH54/s/bOuvk9AxqpjtAY robert-jordens-ed25519"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
harry = {
|
|
||||||
isNormalUser = true;
|
guest = {
|
||||||
extraGroups = ["plugdev" "dialout" "wireshark"];
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDcPNCgtdz8erFPRrAwCr4JrkeYXJUUvoRBgP0X2HlzJgDe1Inuo6sC6CGcO3IXbf4MwVA9XEp8BYPHARVeEHhufg/0wnIABLx2GcK99yxOLDUe4h/3YwtqvOcqHEsDx7w=="
|
|
||||||
];
|
|
||||||
};
|
|
||||||
astro = {
|
|
||||||
isNormalUser = true;
|
|
||||||
extraGroups = ["plugdev" "dialout" "wireshark"];
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGJJTSJdpDh82486uPiMhhyhnci4tScp5uUe7156MBC8 a"
|
|
||||||
];
|
|
||||||
shell = pkgs.bashInteractive;
|
|
||||||
};
|
|
||||||
pca006132 = {
|
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = ["plugdev" "dialout"];
|
extraGroups = ["plugdev" "dialout"];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE/sPOOiw3843+rrcYV2pOVkffNc1xsOgnuCUmy1Fa2VF8x9kqmgQv61sxsuKRkKKoinvqrASxLkWVd6nkiiDuEISibEXs8r1BwuT05cS7RkEhCakSMZ6y/iqOtjt2bx+A=="
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPsv4UMEFV0UHeHdA9R3sC+qoMxrqhcuFqwqWMI4AF/lixwcbRyA8QKiu/7R22m2u6pp+Zk6hYqcxdgClI4uN2oQhVjJX6wEgfT94vC/67OKJI/NNVsR8G0lr0ufCo4Lbw=="
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCrC43AF/aHv9NHormDMw18m/iE3luNc4CIwgPgTClly4b9yRyQGhm4mKkKix07fP9SfdyvUPPrYhwoHhf0zGkfFNE26FIG2Bul9UkZVP3ygnIXHD7sKUJP7Ra4UID6Naf3Mr2Dckh7rAiw8WN2QB+oO2tni3PyceEOdu8OoEsmSu8qusJFVhnaoYJyQflgGl3bFUZkhaf1JKQmv9C92sfKQkrfSNb2dNrc3Oe1uP5VokhLhjsOoDWyJ45a7ru6lr4/Co5sF9xX59cOOBU+ktiOakDI8NLI5AO7R0dCKLW55wUnml5boeCV45p1MPXVEznX8IM6kRgOhVx3fnd0TqV5M8xeY0dk7aTWTFSkIz82xHhKFbce5xx+9MFrlvUgHYVpbIUQTq6HS6cLZEeWHDLuUqbRFB4J7UfieiRZfxWw74Tgyq+HlvlNg/cVn0nhouq6+sY6QI9MGbwbEnjkD5KbSUHUCSeLgNc8pb0RxLkAqPGh8QkYrb6Nudl8HjWfIuZFGrRhcGBySt/oaYUDrUg5VNA98FjQL2QfKRVepvpGgUEGW6eZK9IrYz1Ct30Sb65QujUMRuDnWq1CeulAXCZQHc32wOrHRkMEUdhfOgNojZRTGduPayHXoDq7XB249D2VjH/vEuiLfWNLr+rabGyMUPpQaDypeBgOsUTbceKbDw=="
|
|
||||||
];
|
];
|
||||||
shell = pkgs.zsh;
|
|
||||||
};
|
};
|
||||||
occheung = {
|
occheung = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = ["plugdev" "dialout" "wireshark"];
|
extraGroups = ["plugdev" "dialout"];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPEvmWmxpFpMgp5fpjKud8ev0cyf/+X5fEpQt/YD/+u4mbvZYPE300DLqQ0h/qjgvaGMz1ndf4idYnRdy+plJEC/+hmlRW5NlcpAr3S/LYAisacgKToFVl+MlBo+emS9Ig=="
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPEvmWmxpFpMgp5fpjKud8ev0cyf/+X5fEpQt/YD/+u4mbvZYPE300DLqQ0h/qjgvaGMz1ndf4idYnRdy+plJEC/+hmlRW5NlcpAr3S/LYAisacgKToFVl+MlBo+emS9Ig=="
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
dsleung = {
|
spaqin = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = ["plugdev" "dialout"];
|
extraGroups = ["plugdev" "dialout"];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDbE7HzZKSwGbgRnzwrzCzb3gZKLSritwnEpHS4sa9oXJ5oLFkuFZOpPYDeiMlbUJ9jCk5FRmkLYIkrbz06SUr7P/eUjxu79ENi3RhfVu+ZrrPvgkhKvM/CiXvw3xCOu0w=="
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOtmlQmIK/cEUkcwA/y9jC4AohjoEmikerpxzPhZZtOcENidN/vFum58jIcSxBvjHnILOzhfCTeLvbvGbQOFE53a7FOyEHmIzXRKS86Mg5bPHUBJxRSq9MjulGZXES3HOQ=="
|
||||||
|
];
|
||||||
|
shell = pkgs.zsh;
|
||||||
|
};
|
||||||
|
srayman89 = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout" "libvirtd"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBMoGOV9HoFkm6S6zMfOc8ivUcGzKFxuqpmOXKQtg2nn5Kh6ByMuuAHFlvKISILBaWgXN8lPQN9VjLuXV93oG4Pe7u8EVw20IGbA6RZ4Pnnr1xQBESPbye+72taLvyQlxGA=="
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
cw = {
|
esavkin = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout" "libvirtd" "wireshark"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBLDJI4GFLBmScbeR8Jh4Gi8A/2nuGlYtFTJVT+Es/bzdiPRk8DLG62T0hyRR+8LfHjbrCsDuYFNztT8hHGXd7h3xp3y2X7ArkJo8xUK5QxGd5D2Zn4ANfZTTVkoGlEHbFA=="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
flo = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = ["plugdev" "dialout"];
|
extraGroups = ["plugdev" "dialout"];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBKsbGwnWUZpH7uyli0RR1oOCZJaVGNg/ZeIP3BIjowr2I9YSDqlbgXG3grgLAxiNL7a/RRh9naR+5ViWpoZGSt90RouUK3S6u7JR7oso7tcI50/9xro8g3ZDwCncGxkXDA=="
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF4ZYNBYqJPQCKBYjMatFj5eGMyzh/X2TSraJEG6XBdg3jnJ3WcsOd7sm+vx+o9Y1EJ2kvwW/Vy9c3OYVU2U45njox//sKtt8Eyzszws3EYJqHQ6KAwXtW9ao4aamRtK3Q=="
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
srenblad = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBLoMzO8XIkUTKUC0R05EmXn3V6gm2oMvXhh+j68G9TDBeb8x0WFkz16NPclsXdMcb2dFhtLmxUHwB5L4zWSuyYkqr0YRrtly3uwXe5Wnyz1ZAkxoq7YjQlanWSri11U8xw=="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
linuswck = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout" "wireshark" "libvirtd"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBAFYwmik6/xY1vb9aKBOpKklKOwSJJ0PEgNwWNULghZGJ0g4CTk04LXLSMYBm1SW74df8YMgaE/eoidq6smN6hKIgo8s3qPQGZAi4UXffMs2ciqXNa/zZcCu3PyZvyksxA=="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
morgan = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout" "wireshark" "libvirtd"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDXMbJEPn0mM2Bgt6eMAd+c0J5oPSvquZG+BxKdUf0qbeQldRaoB26NHMZnLte/fS00U/cqStLWDiwtEvH5WlbbawsMBymm65zbWMByebXhBDjdr6a1kkOFcKJvAL9qVBQ=="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
atse = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJHMX1YDnBPQfZyGVtc93u4TIFWqnHEe6WB/eTeiOjFulitXzGfhsODZ08GzTi2+YKk7spRiPKNwRPTKFuW2PPe3Xig8b75qRMIeIVX3b7e0i6xP85eg4jdiz0LD2YGUHQ=="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
derppening = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOKwN4ui94QfouYYlkI1lc3WgtjURVYLTdAizJIBnY3dNRNblAiuvTD4pQ+LEI+eOTg4SnQz1NeqH4YOQhbT5+/nZojvGTb3UVN13ZYND+Gci3DdqB2mwIYop7kMXwHgLQ=="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
therobs12 = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBK1tUg7TtceARRnGI80Ai5kNFolFfZ++LH9v1UoRCiJdxeQWPdNYO0Gj7+ejJvgZXwvN4yHGgcZHraEml4Mj/dKrEMFygfuYLDRmXtPFwX6TNMrWlxMhPzuNY+yCaxlqYg=="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
dpn = {
|
dpn = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = ["plugdev" "dialout" "wireshark"];
|
extraGroups = ["plugdev" "dialout"];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDB/3vRS5HKRz8RHTqrlb5P54A2UJnrffhnuqoHwy5OLr+h5j6MA9yu8LYCBx87LI4M4AKc6eJo//e793mqYXGq8Gp4MMzxglgKEnrw0a41CerXZNt5M4c9Jy5io1L73etoY0RwuexH27RIGrJ0nNazlLEmOr5J4Z/sqikDBKi8f8Z0BS5/SlkhSRCtl6T3uDM7W3Wl04ZJF/vP0tEuvU9lYk99ujt9Ll/D2TXfJTezBtugADas5Te+D5I1RDF9Bc2L7zp6nP/TEzvXwA8+rfAf+Prd4MpPGt0OtLxWgjo21lx7gKM9WoZMBL6qjn3iemveEVu48yoi1MpHyTmT/qwTYWk4hVz7LdqVUYPszAVxFr89A4qfmE4AWSEOqALeaOM9jUJK4ZO33fT94HpgtjKJut+vdQfjRl2caxOJu34BBFn2cYMOZaDIUCuNOmYGhj3nzI/wzXB7EH4J+KCEyAEGRYakADqttBRCD3Znw6mzlOjfu4bMlylrPb9/Ajsafwk="
|
|
||||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGChLocYJi8XcSJkIjT2Olm3jPGjtRq5aORa5G9F3OqmjCfvav9Q5+2Mc64XqHtNTffnJuDe4gv+lVJatC0URvPs2HyxXmxRK0jgkkLSUsV2SYLlgMqHW3jsrdh6wKBmkg=="
|
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGChLocYJi8XcSJkIjT2Olm3jPGjtRq5aORa5G9F3OqmjCfvav9Q5+2Mc64XqHtNTffnJuDe4gv+lVJatC0URvPs2HyxXmxRK0jgkkLSUsV2SYLlgMqHW3jsrdh6wKBmkg=="
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
tom = {
|
|
||||||
isNormalUser = true;
|
|
||||||
extraGroups = ["plugdev" "dialout"];
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDMviQek/1Wj525Y5QQb3fXimJ9srOgWJNBxKKB5xfOzEzlU/MQr49sUSyq1+wUXOc2lHjQQb4aNbs8QyzhgynvlZZ4C/scFXLv83V8SFd8fXb8YiJ5OXBCxiHAZWJF/99kxQNeLvp3qvU+hWG3nLHd6NDTbyqG+EIEaZkJsVbdCzL/ERUbCZPNkfgY5zv62i9zR8XJtt77lyCprOs4q27wD+FplkjN3skeWJYr0F+yuf2DEC1ZrOS1uYHVgPlOZRSQq8qtWr4K4ZMrFJ0Ul7Qzj/GjtqH59QZFcVgoHJhlSM5MUNn863IKuLPmHOsTYqA57bPj+vulMZwt63Qw0ehpVZnUo3MZjfI/fS5Ox8c0B+7/JmGXxQVe+mQ6feg24h3C3+npzI6VbGXr09+ka36d7bRDJdY6/LEhQZTiwXrwOxstFjbEucGDPFx0rsqDxPeQ77mA0GQw2J/hYr6kc+KDIipclxqq6tE6LEYaAzeiTePU+QSutLsOzEpXezY3vINd/Tp8oySQBliseKsByPV8m37egTHheLNbVvh6a4sfhm68MGDYNBAKGHyMpnnDf/G1PVf97wq0YpQWoCrYNbp7QQZST0UjEk8hARnI/UuZtkYOaube0lcO0zaMUtmX8Qq4dq+RMblcwjWVsqExljFNEhjJqRRY7ZfpJ5OdeiXFLQ=="
|
|
||||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJ+FieYdkTS3BomeEVp7SMGD3HYDzdQHKi1WgqiFF5c3CYjFiwc/W/NrsCavEkLM9GrLKS1OKxHlG6gpsMGxiHuidoK7NDd3NhHL2jJFzH7haFktJ5DrkfRPPi4QPscZPg=="
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/c7fa9c3e-56ca-4258-a49c-3f064efbd58c";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/76A2-F01F";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.enp86s0.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "23.05";
|
||||||
|
}
|
|
@ -2,20 +2,47 @@
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
let
|
let
|
||||||
m-labs = import (fetchTarball https://nixbld.m-labs.hk/channel/custom/artiq/full/artiq-full/nixexprs.tar.xz) { inherit pkgs; };
|
artiq = builtins.getFlake git+https://github.com/m-labs/artiq.git;
|
||||||
pkgs-unstable = import (fetchTarball https://github.com/NixOS/nixpkgs/archive/master.tar.gz) {};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
deployment.targetHost = host;
|
deployment.targetHost = host;
|
||||||
|
deployment.hasFastConnection = true;
|
||||||
|
nix.nixPath = [ "nixpkgs=${pkgs.path}" ];
|
||||||
|
programs.command-not-found.dbPath = "${pkgs.path}/programs.sqlite";
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.memtest86.enable = true;
|
||||||
|
boot.loader.grub.memtest86.enable = true;
|
||||||
|
|
||||||
disabledModules = [ "security/pam.nix" ];
|
|
||||||
imports =
|
imports =
|
||||||
[
|
[
|
||||||
(./. + "/${host}-hardware-configuration.nix")
|
(./. + "/${host}-hardware-configuration.nix")
|
||||||
./pam_p11
|
./avscan-module.nix
|
||||||
];
|
];
|
||||||
|
nixpkgs.config.packageOverrides = super: let self = super.pkgs; in {
|
||||||
|
libp11 = super.libp11.override({ openssl = super.openssl_1_1; });
|
||||||
|
pam_p11 = super.pam_p11.overrideAttrs(oa: {
|
||||||
|
patches = [];
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace src/match_openssh.c --replace \
|
||||||
|
'"%s/.ssh/authorized_keys", pw->pw_dir)' \
|
||||||
|
'"/etc/ssh/authorized_keys.d/%s", pw->pw_name)'
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
gnome = super.gnome // {
|
||||||
|
gnome-keyring = super.gnome.gnome-keyring.overrideAttrs(oa: {
|
||||||
|
configureFlags = oa.configureFlags ++ ["--disable-ssh-agent"];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
nixpkgs.config.permittedInsecurePackages = [
|
||||||
|
"openssl-1.1.1w"
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.binfmt.emulatedSystems = [ "armv7l-linux" ];
|
||||||
|
|
||||||
networking.hostName = host;
|
networking.hostName = host;
|
||||||
|
networking.firewall.allowedTCPPorts = [ 1883 ];
|
||||||
|
networking.firewall.allowedUDPPorts = [ 1883 ];
|
||||||
|
|
||||||
time.timeZone = "Asia/Hong_Kong";
|
time.timeZone = "Asia/Hong_Kong";
|
||||||
|
|
||||||
|
@ -23,46 +50,63 @@ in
|
||||||
# $ nix search wget
|
# $ nix search wget
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
opensc yubikey-manager yubikey-manager-qt
|
opensc yubikey-manager yubikey-manager-qt yubico-piv-tool
|
||||||
wget vim gitAndTools.gitFull firefox chromium thunderbird hexchat
|
wget vim gitAndTools.gitFull sshfs
|
||||||
usbutils pciutils file lm_sensors audacious acpi
|
firefox
|
||||||
|
thunderbird
|
||||||
|
chromium
|
||||||
|
usbutils pciutils uhubctl file lm_sensors audacious acpi
|
||||||
gimp imagemagick
|
gimp imagemagick
|
||||||
(python3.withPackages(ps: with ps; [ numpy scipy matplotlib qtconsole regex ]))
|
(python3.withPackages(ps: with ps; [ numpy scipy matplotlib qtconsole regex jinja2 ]))
|
||||||
|
texlive.combined.scheme-full
|
||||||
mosh psmisc libreoffice-fresh
|
mosh psmisc libreoffice-fresh
|
||||||
gtkwave telnet unzip zip gnupg
|
inkscape
|
||||||
gnome3.gnome-tweaks
|
xournal
|
||||||
|
xsane
|
||||||
|
gtkwave unzip zip gnupg
|
||||||
|
gnome-tweaks
|
||||||
|
ghex
|
||||||
jq sublime3 rink qemu_kvm
|
jq sublime3 rink qemu_kvm
|
||||||
tmux xc3sprog m-labs.openocd screen gdb minicom picocom tigervnc
|
tmux screen gdb minicom picocom
|
||||||
|
artiq.packages.x86_64-linux.openocd-bscanspi
|
||||||
|
xc3sprog
|
||||||
|
gqrx
|
||||||
emacs bat ripgrep
|
emacs bat ripgrep
|
||||||
pkgs-unstable.xpra
|
guake
|
||||||
pkgs-unstable.rust-analyzer
|
vscodium
|
||||||
(pkgs-unstable.vscode-with-extensions.override {
|
waypipe
|
||||||
vscodeExtensions = [
|
virt-manager spice-gtk
|
||||||
pkgs-unstable.vscode-extensions.matklad.rust-analyzer
|
kicad
|
||||||
];
|
any-nix-shell
|
||||||
})
|
|
||||||
(import ./fish-nix-shell)
|
|
||||||
];
|
];
|
||||||
programs.wireshark.enable = true;
|
programs.wireshark.enable = true;
|
||||||
programs.wireshark.package = pkgs.wireshark;
|
programs.wireshark.package = pkgs.wireshark;
|
||||||
|
virtualisation.libvirtd.enable = true;
|
||||||
|
virtualisation.libvirtd.qemu.ovmf.enable = true;
|
||||||
|
security.wrappers.spice-client-glib-usb-acl-helper = {
|
||||||
|
source = "${pkgs.spice-gtk}/bin/spice-client-glib-usb-acl-helper";
|
||||||
|
owner = "root";
|
||||||
|
group = "root";
|
||||||
|
setuid = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.avscan.enable = true;
|
||||||
|
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
services.openssh.forwardX11 = true;
|
services.openssh.authorizedKeysInHomedir = false;
|
||||||
services.openssh.passwordAuthentication = false;
|
services.openssh.settings.PasswordAuthentication = false;
|
||||||
services.openssh.extraConfig =
|
services.openssh.extraConfig =
|
||||||
''
|
''
|
||||||
StreamLocalBindUnlink yes
|
StreamLocalBindUnlink yes
|
||||||
'';
|
'';
|
||||||
programs.mosh.enable = true;
|
programs.mosh.enable = true;
|
||||||
|
|
||||||
hardware.u2f.enable = true;
|
|
||||||
services.pcscd.enable = true;
|
services.pcscd.enable = true;
|
||||||
programs.ssh.extraConfig =
|
programs.ssh.extraConfig =
|
||||||
''
|
''
|
||||||
PKCS11Provider "${pkgs.opensc}/lib/opensc-pkcs11.so"
|
PKCS11Provider "${pkgs.opensc}/lib/opensc-pkcs11.so"
|
||||||
'';
|
'';
|
||||||
programs.ssh.startAgent = true;
|
programs.ssh.startAgent = true;
|
||||||
services.gnome3.gnome-keyring.enable = pkgs.lib.mkForce false;
|
|
||||||
programs.ssh.agentPKCS11Whitelist = "${pkgs.opensc}/lib/opensc-pkcs11.so";
|
programs.ssh.agentPKCS11Whitelist = "${pkgs.opensc}/lib/opensc-pkcs11.so";
|
||||||
security.pam.p11.enable = true;
|
security.pam.p11.enable = true;
|
||||||
|
|
||||||
|
@ -82,78 +126,54 @@ in
|
||||||
};
|
};
|
||||||
services.avahi = {
|
services.avahi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
nssmdns = true;
|
nssmdns4 = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Enable sound.
|
hardware.graphics.enable32Bit = true;
|
||||||
sound.enable = true;
|
|
||||||
hardware.pulseaudio = {
|
|
||||||
enable = true;
|
|
||||||
extraModules = [ pkgs.pulseaudio-modules-bt ];
|
|
||||||
package = pkgs.pulseaudioFull;
|
|
||||||
};
|
|
||||||
|
|
||||||
i18n.inputMethod = {
|
fonts.packages = [ pkgs.noto-fonts pkgs.noto-fonts-cjk-sans pkgs.noto-fonts-emoji pkgs.noto-fonts-extra pkgs.emacs-all-the-icons-fonts ];
|
||||||
enabled = "fcitx";
|
|
||||||
fcitx.engines = with pkgs.fcitx-engines; [ table-extra m17n ];
|
|
||||||
};
|
|
||||||
fonts.fonts = [ pkgs.noto-fonts pkgs.noto-fonts-cjk pkgs.noto-fonts-emoji pkgs.noto-fonts-extra pkgs.emacs-all-the-icons-fonts ];
|
|
||||||
|
|
||||||
# Enable the X11 windowing system.
|
# Enable the X11 windowing system.
|
||||||
services.xserver.enable = true;
|
services.xserver.enable = true;
|
||||||
services.xserver.layout = "us";
|
services.xserver.xkb.layout = "us";
|
||||||
services.xserver.xkbOptions = "eurosign:e";
|
services.xserver.xkb.options = "eurosign:e";
|
||||||
|
|
||||||
# Enable touchpad support.
|
|
||||||
services.xserver.libinput.enable = true;
|
|
||||||
|
|
||||||
services.xserver.displayManager.gdm.enable = true;
|
services.xserver.displayManager.gdm.enable = true;
|
||||||
services.xserver.displayManager.gdm.autoSuspend = false;
|
services.xserver.desktopManager.gnome.enable = true;
|
||||||
powerManagement.enable = false;
|
environment.gnome.excludePackages = [ pkgs.epiphany ];
|
||||||
services.xserver.desktopManager.gnome3.enable = true;
|
|
||||||
environment.gnome3.excludePackages = [ pkgs.epiphany pkgs.gnome3.geary ];
|
systemd.suppressedSystemUnits = [
|
||||||
|
"hibernate.target"
|
||||||
|
"suspend.target"
|
||||||
|
"suspend-then-hibernate.target"
|
||||||
|
"sleep.target"
|
||||||
|
"hybrid-sleep.target"
|
||||||
|
"systemd-hibernate.service"
|
||||||
|
"systemd-hybrid-sleep.service"
|
||||||
|
"systemd-suspend.service"
|
||||||
|
"systemd-suspend-then-hibernate.service"
|
||||||
|
];
|
||||||
|
|
||||||
hardware.bluetooth.enable = true;
|
hardware.bluetooth.enable = true;
|
||||||
|
|
||||||
|
programs.zsh.enable = true;
|
||||||
programs.fish.enable = true;
|
programs.fish.enable = true;
|
||||||
programs.fish.promptInit = ''
|
programs.fish.promptInit = ''
|
||||||
fish-nix-shell --info-right | source
|
any-nix-shell fish --info-right | source
|
||||||
'';
|
'';
|
||||||
users.mutableUsers = false;
|
users.mutableUsers = false;
|
||||||
users.defaultUserShell = pkgs.fish;
|
users.defaultUserShell = pkgs.fish;
|
||||||
users.extraGroups.plugdev = { };
|
users.extraGroups.plugdev = { };
|
||||||
users.extraUsers = import ./common-users.nix { inherit pkgs; };
|
users.extraUsers = import ./common-users.nix { inherit pkgs; };
|
||||||
security.sudo.wheelNeedsPassword = false;
|
security.sudo.wheelNeedsPassword = false;
|
||||||
services.udev.packages = [ m-labs.openocd ];
|
services.udev.packages = [ artiq.packages.x86_64-linux.openocd-bscanspi ];
|
||||||
services.udev.extraRules = ''
|
services.udev.extraRules = (import ./extra-udev.nix);
|
||||||
# leaf maple
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0003", MODE="0660", GROUP="plugdev"
|
nix.settings.trusted-public-keys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0004", MODE="0660", GROUP="plugdev"
|
nix.settings.substituters = ["https://nixbld.m-labs.hk?priority=10"];
|
||||||
# STM32 devkit
|
nix.settings.extra-sandbox-paths = ["/opt"];
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374e", MODE="0660", GROUP="plugdev"
|
|
||||||
# glasgow
|
nix.extraOptions = ''
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="20b7", ATTRS{idProduct}=="9db1", MODE="0660", GROUP="plugdev"
|
experimental-features = nix-command flakes impure-derivations
|
||||||
# hackrf
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="6089", MODE="0660", GROUP="plugdev"
|
|
||||||
# bladerf
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="2cf0", ATTRS{idProduct}=="5250", MODE="0660", GROUP="plugdev"
|
|
||||||
# personal measurement device
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="09db", ATTRS{idProduct}=="007a", MODE="0660", GROUP="plugdev"
|
|
||||||
# saleae
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0925", ATTRS{idProduct}=="3881", MODE="0660", GROUP="plugdev"
|
|
||||||
# ocean optics
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="2457", ATTRS{idProduct}=="1002", MODE="0660", GROUP="plugdev"
|
|
||||||
# yubikey
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0116", MODE="0660", GROUP="plugdev"
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
nix.binaryCachePublicKeys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
|
|
||||||
nix.binaryCaches = ["https://nixbld.m-labs.hk" "https://cache.nixos.org"];
|
|
||||||
nix.sandboxPaths = ["/opt"];
|
|
||||||
|
|
||||||
# This value determines the NixOS release with which your system is to be
|
|
||||||
# compatible, in order to avoid breaking some software such as database
|
|
||||||
# servers. You should change this only after NixOS release notes say you
|
|
||||||
# should.
|
|
||||||
system.stateVersion = "19.03"; # Did you read the comment?
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
''
|
||||||
|
# hackrf
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="6089", MODE="0660", GROUP="plugdev"
|
||||||
|
# bladerf
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="2cf0", ATTRS{idProduct}=="5250", MODE="0660", GROUP="plugdev"
|
||||||
|
# personal measurement device
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="09db", ATTRS{idProduct}=="007a", MODE="0660", GROUP="plugdev"
|
||||||
|
# saleae
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="0925", ATTRS{idProduct}=="3881", MODE="0660", GROUP="plugdev"
|
||||||
|
# ocean optics
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="2457", ATTRS{idProduct}=="1002", MODE="0660", GROUP="plugdev"
|
||||||
|
# yubikey
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0116", MODE="0660", GROUP="plugdev"
|
||||||
|
# label printer
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="07cf", ATTRS{idProduct}=="4204", MODE="0660", GROUP="plugdev"
|
||||||
|
# dfu/booster
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE="0660", GROUP="plugdev"
|
||||||
|
# Renkforce USB hub with power control
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="0812", MODE="0660", GROUP="plugdev"
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="2812", MODE="0660", GROUP="plugdev"
|
||||||
|
# LibreVNA
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="4121", MODE="0660", GROUP="plugdev"
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="4121", MODE="0660", GROUP="plugdev"
|
||||||
|
# DSLogic
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="2a0e", ATTRS{idProduct}=="0020", MODE="0660", GROUP="plugdev"
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="2a0e", ATTRS{idProduct}=="0034", MODE="0660", GROUP="plugdev"
|
||||||
|
''
|
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2018 haslersn
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
|
@ -1,50 +0,0 @@
|
||||||
# fish-nix-shell
|
|
||||||
fish support for the *nix-shell* environment of the Nix package manager.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Installation in the user environment
|
|
||||||
|
|
||||||
Execute
|
|
||||||
|
|
||||||
```
|
|
||||||
nix-env -if https://github.com/haslersn/fish-nix-shell/archive/master.tar.gz
|
|
||||||
```
|
|
||||||
|
|
||||||
and add the following to your *~/.config/fish/config.fish*. Create it if it doesn't exist.
|
|
||||||
|
|
||||||
```
|
|
||||||
fish-nix-shell --info-right | source
|
|
||||||
```
|
|
||||||
|
|
||||||
### System-wide installation
|
|
||||||
|
|
||||||
Add the package to your */etc/nixos/configuration.nix*:
|
|
||||||
|
|
||||||
```
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
#
|
|
||||||
# Other packages here ...
|
|
||||||
#
|
|
||||||
(import (fetchGit "https://github.com/haslersn/fish-nix-shell"))
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
and then execute: `sudo nixos-rebuild switch`
|
|
||||||
|
|
||||||
If you want to configure it system-wide, also add:
|
|
||||||
|
|
||||||
```
|
|
||||||
programs.fish.enable = true;
|
|
||||||
programs.fish.promptInit = ''
|
|
||||||
fish-nix-shell --info-right | source
|
|
||||||
'';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flags
|
|
||||||
|
|
||||||
The `fish-nix-shell` command **optionally** takes the following flags:
|
|
||||||
|
|
||||||
| Flag | Meaning |
|
|
||||||
| - | - |
|
|
||||||
| `--info-right` | While in a *fish-nix-shell*, display information about the loaded packages at the right.
|
|
|
@ -1,34 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
function init_fish () {
|
|
||||||
cat <<EOF
|
|
||||||
|
|
||||||
# Overwrite the nix-shell command
|
|
||||||
function nix-shell
|
|
||||||
fish-nix-shell-wrapper \$argv
|
|
||||||
set -gx FISH_NIX_SHELL_EXIT_STATUS \$status
|
|
||||||
end
|
|
||||||
EOF
|
|
||||||
for arg in "$@"; do
|
|
||||||
case "$arg" in
|
|
||||||
--info-right)
|
|
||||||
cat <<EOF
|
|
||||||
|
|
||||||
# Print additional information inside a nix-shell environment
|
|
||||||
function fish_right_prompt
|
|
||||||
nix-shell-info
|
|
||||||
set -e FISH_NIX_SHELL_EXIT_STATUS
|
|
||||||
end
|
|
||||||
EOF
|
|
||||||
;;
|
|
||||||
*) exit 1;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
# If you see this output, you probably forgot to pipe this output into 'source':
|
|
||||||
# fish-nix-shell $@ | source
|
|
||||||
EOF
|
|
||||||
|
|
||||||
init_fish "$@"
|
|
|
@ -1,22 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
fns () {
|
|
||||||
pkgs=$FISH_NIX_SHELL_PKGS
|
|
||||||
for arg in "$@"; do
|
|
||||||
if [[ $arg == -* ]]; then
|
|
||||||
pkg=
|
|
||||||
if [[ $arg == --pure ]] || [[ $arg == --command ]] || [[ $arg == --run ]]; then
|
|
||||||
command nix-shell $@
|
|
||||||
return
|
|
||||||
elif [[ $arg == -p ]] || [[ $arg == --packages ]]; then
|
|
||||||
pkg=1
|
|
||||||
fi
|
|
||||||
elif [[ $pkg == 1 ]]; then
|
|
||||||
pkgs+=" "$arg
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ -n $name ]] && [[ $name != shell ]]; then
|
|
||||||
pkgs+=" "$name
|
|
||||||
fi
|
|
||||||
env FISH_NIX_SHELL_PKGS="$pkgs" nix-shell "$@" --command fish
|
|
||||||
}
|
|
||||||
fns "$@"
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
if [[ $IN_NIX_SHELL != "" ]]; then
|
|
||||||
printf "\033[1;32m"
|
|
||||||
output=$(echo $FISH_NIX_SHELL_PKGS | xargs)
|
|
||||||
if [[ -n $name ]] && [[ $name != shell ]]; then
|
|
||||||
output+=" "$name
|
|
||||||
fi
|
|
||||||
if [[ -n $output ]]; then
|
|
||||||
output=$(echo $output $additional_pkgs | tr ' ' '\n' | sort -u | tr '\n' ' ' | xargs)
|
|
||||||
printf "$output "
|
|
||||||
else
|
|
||||||
printf "[unknown nix-shell] "
|
|
||||||
fi
|
|
||||||
printf "\033[0m"
|
|
||||||
elif [[ $FISH_NIX_SHELL_EXIT_STATUS ]]; then
|
|
||||||
if [[ $FISH_NIX_SHELL_EXIT_STATUS == 0 ]]; then
|
|
||||||
printf "\033[1;36mexited nix-shell \033[0m"
|
|
||||||
else
|
|
||||||
printf "\033[1;31mERROR \033[0m"
|
|
||||||
fi
|
|
||||||
fi
|
|
|
@ -1,16 +0,0 @@
|
||||||
with import <nixpkgs> {}; stdenv.mkDerivation rec {
|
|
||||||
name = "fish-nix-shell";
|
|
||||||
src = fetchGit "https://github.com/haslersn/fish-nix-shell";
|
|
||||||
nativeBuildInputs = [ makeWrapper ];
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
cp LICENSE $out
|
|
||||||
cp -r bin $out
|
|
||||||
wrapProgram $out/bin/fish-nix-shell
|
|
||||||
wrapProgram $out/bin/fish-nix-shell-wrapper --prefix PATH ":" ${fish}/bin
|
|
||||||
wrapProgram $out/bin/nix-shell-info
|
|
||||||
'';
|
|
||||||
meta.description = "fish support for the nix-shell environment of the Nix package manager.";
|
|
||||||
meta.license = "MIT";
|
|
||||||
meta.homepage = https://github.com/haslersn/fish-nix-shell;
|
|
||||||
}
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.blacklistedKernelModules = [ "iwlwifi" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
boot.kernelParams = ["intel_idle.max_cstate=1"];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/37e69920-a60d-4cb0-ae2f-b812f7a35dc8";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/A33B-F001";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "21.05";
|
||||||
|
}
|
|
@ -1,6 +1,3 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -21,13 +18,18 @@
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-uuid/8C30-F6DC";
|
{ device = "/dev/disk/by-uuid/8C30-F6DC";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
|
|
||||||
nix.maxJobs = lib.mkDefault 16;
|
nix.settings.max-jobs = lib.mkDefault 16;
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "19.03";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -21,13 +18,18 @@
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-uuid/E085-5F21";
|
{ device = "/dev/disk/by-uuid/E085-5F21";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
|
|
||||||
nix.maxJobs = lib.mkDefault 16;
|
nix.settings.max-jobs = lib.mkDefault 16;
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "19.03";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,42 @@
|
||||||
{ config, lib, pkgs, ... }:
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod" ];
|
boot.initrd.availableKernelModules = [ "ehci_pci" "ata_piix" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" =
|
||||||
{ device = "/dev/disk/by-uuid/62a38d9c-452c-4648-be12-6131e95b8276";
|
{ device = "/dev/disk/by-uuid/3dca09c8-f725-416a-9f89-b69297698ca9";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
|
||||||
{ device = "/dev/disk/by-uuid/88F6-46F2";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
|
|
||||||
nix.maxJobs = lib.mkDefault 8;
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.enp5s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
boot.loader.grub.enable = true;
|
||||||
|
boot.loader.grub.device = "/dev/sda";
|
||||||
|
|
||||||
|
nixpkgs.config.nvidia.acceptLicense = true;
|
||||||
|
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
|
||||||
|
services.xserver.videoDrivers = [ "nvidia" ];
|
||||||
|
services.xserver.displayManager.gdm.wayland = false;
|
||||||
|
|
||||||
|
system.stateVersion = "23.05";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "ahci" "nvme" "usbhid" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/315af039-6799-43ac-8999-7da69a6fbd1e";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/45B7-790E";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.enp86s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
system.stateVersion = "24.05";
|
||||||
|
}
|
118
nixops/light.nix
118
nixops/light.nix
|
@ -1,118 +0,0 @@
|
||||||
{ host }:
|
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
|
||||||
{
|
|
||||||
deployment.targetHost = host;
|
|
||||||
|
|
||||||
disabledModules = [ "security/pam.nix" ];
|
|
||||||
imports =
|
|
||||||
[
|
|
||||||
(./. + "/${host}-hardware-configuration.nix")
|
|
||||||
./pam_p11
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.hostName = host;
|
|
||||||
|
|
||||||
time.timeZone = "Asia/Hong_Kong";
|
|
||||||
|
|
||||||
# List packages installed in system profile. To search, run:
|
|
||||||
# $ nix search wget
|
|
||||||
documentation.enable = false;
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
opensc
|
|
||||||
wget vim git firefox usbutils pciutils file lm_sensors acpi
|
|
||||||
gimp imagemagick
|
|
||||||
(python3.withPackages(ps: with ps; [ numpy scipy ]))
|
|
||||||
psmisc
|
|
||||||
telnet unzip zip gnupg
|
|
||||||
sublime3 rink
|
|
||||||
tmux screen tigervnc
|
|
||||||
(import ./fish-nix-shell)
|
|
||||||
];
|
|
||||||
programs.wireshark.enable = true;
|
|
||||||
|
|
||||||
services.openssh.enable = true;
|
|
||||||
services.openssh.forwardX11 = true;
|
|
||||||
services.openssh.passwordAuthentication = false;
|
|
||||||
services.openssh.extraConfig =
|
|
||||||
''
|
|
||||||
StreamLocalBindUnlink yes
|
|
||||||
'';
|
|
||||||
programs.mosh.enable = true;
|
|
||||||
|
|
||||||
hardware.u2f.enable = true;
|
|
||||||
services.pcscd.enable = true;
|
|
||||||
programs.ssh.extraConfig =
|
|
||||||
''
|
|
||||||
PKCS11Provider "${pkgs.opensc}/lib/opensc-pkcs11.so"
|
|
||||||
'';
|
|
||||||
programs.ssh.startAgent = true;
|
|
||||||
programs.ssh.agentPKCS11Whitelist = "${pkgs.opensc}/lib/opensc-pkcs11.so";
|
|
||||||
security.pam.p11.enable = true;
|
|
||||||
|
|
||||||
# Enable CUPS to print documents.
|
|
||||||
services.printing = {
|
|
||||||
enable = true;
|
|
||||||
extraConf =
|
|
||||||
''
|
|
||||||
Browsing Off
|
|
||||||
BrowseLocalProtocols none
|
|
||||||
'';
|
|
||||||
browsedConf =
|
|
||||||
''
|
|
||||||
BrowseRemoteProtocols none
|
|
||||||
BrowseProtocols none
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
services.avahi = {
|
|
||||||
enable = true;
|
|
||||||
nssmdns = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Enable sound.
|
|
||||||
sound.enable = true;
|
|
||||||
hardware.pulseaudio = {
|
|
||||||
enable = true;
|
|
||||||
extraModules = [ pkgs.pulseaudio-modules-bt ];
|
|
||||||
package = pkgs.pulseaudioFull;
|
|
||||||
};
|
|
||||||
|
|
||||||
i18n.inputMethod = {
|
|
||||||
enabled = "fcitx";
|
|
||||||
fcitx.engines = with pkgs.fcitx-engines; [ table-extra m17n ];
|
|
||||||
};
|
|
||||||
fonts.fonts = [ pkgs.noto-fonts pkgs.noto-fonts-cjk pkgs.noto-fonts-emoji pkgs.noto-fonts-extra ];
|
|
||||||
|
|
||||||
# Enable the X11 windowing system.
|
|
||||||
services.xserver.enable = true;
|
|
||||||
services.xserver.layout = "us";
|
|
||||||
services.xserver.xkbOptions = "eurosign:e";
|
|
||||||
|
|
||||||
# Enable touchpad support.
|
|
||||||
services.xserver.libinput.enable = true;
|
|
||||||
|
|
||||||
services.xserver.displayManager.lightdm.enable = true;
|
|
||||||
services.xserver.desktopManager.xfce.enable = true;
|
|
||||||
|
|
||||||
programs.fish.enable = true;
|
|
||||||
programs.fish.promptInit = ''
|
|
||||||
fish-nix-shell --info-right | source
|
|
||||||
'';
|
|
||||||
users.mutableUsers = false;
|
|
||||||
users.defaultUserShell = pkgs.fish;
|
|
||||||
users.extraGroups.plugdev = { };
|
|
||||||
users.extraUsers = import ./common-users.nix { inherit pkgs; };
|
|
||||||
|
|
||||||
security.sudo.wheelNeedsPassword = false;
|
|
||||||
|
|
||||||
nix.binaryCachePublicKeys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
|
|
||||||
nix.binaryCaches = ["https://nixbld.m-labs.hk" "https://cache.nixos.org"];
|
|
||||||
nix.sandboxPaths = ["/opt"];
|
|
||||||
|
|
||||||
# This value determines the NixOS release with which your system is to be
|
|
||||||
# compatible, in order to avoid breaking some software such as database
|
|
||||||
# servers. You should change this only after NixOS release notes say you
|
|
||||||
# should.
|
|
||||||
system.stateVersion = "19.03"; # Did you read the comment?
|
|
||||||
}
|
|
|
@ -1,15 +1,23 @@
|
||||||
{
|
{
|
||||||
|
network.storage.legacy = {
|
||||||
|
databasefile = "~/.nixops/deployments.nixops";
|
||||||
|
};
|
||||||
|
|
||||||
network.enableRollback = true;
|
network.enableRollback = true;
|
||||||
|
|
||||||
rpi-1 = import ./rpi.nix { host = "rpi-1"; rpi4 = false; };
|
rpi-1 = import ./rpi.nix { host = "rpi-1"; rpi4 = true; };
|
||||||
rpi-2 = import ./rpi.nix { host = "rpi-2"; rpi4 = false; };
|
|
||||||
rpi-3 = import ./rpi.nix { host = "rpi-3"; rpi4 = true; };
|
|
||||||
rpi-4 = import ./rpi.nix { host = "rpi-4"; rpi4 = true; };
|
rpi-4 = import ./rpi.nix { host = "rpi-4"; rpi4 = true; };
|
||||||
rpi-5 = import ./rpi.nix { host = "rpi-5"; rpi4 = true; };
|
|
||||||
juno = import ./desktop.nix { host = "juno"; };
|
|
||||||
zeus = import ./desktop.nix { host = "zeus"; };
|
zeus = import ./desktop.nix { host = "zeus"; };
|
||||||
hera = import ./desktop.nix { host = "hera"; };
|
hera = import ./desktop.nix { host = "hera"; };
|
||||||
hestia = import ./desktop.nix { host = "hestia"; };
|
hestia = import ./desktop.nix { host = "hestia"; };
|
||||||
chiron = import ./desktop.nix { host = "chiron"; };
|
chiron = import ./desktop.nix { host = "chiron"; };
|
||||||
cnc = import ./light.nix { host = "cnc"; };
|
old-nixbld = import ./desktop.nix { host = "old-nixbld"; };
|
||||||
|
franz = import ./desktop.nix { host = "franz"; };
|
||||||
|
juno = import ./desktop.nix { host = "juno"; };
|
||||||
|
demeter = import ./desktop.nix { host = "demeter"; };
|
||||||
|
vulcan = import ./desktop.nix { host = "vulcan"; };
|
||||||
|
rc = import ./desktop.nix { host = "rc"; };
|
||||||
|
athena = import ./desktop.nix { host = "athena"; };
|
||||||
|
jupiter = import ./desktop.nix { host = "jupiter"; };
|
||||||
|
saturn = import ./desktop.nix { host = "saturn"; };
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-amd" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/69b15848-1cfc-4e3e-91de-1df0d2fc7a80";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/D0A3-DDAE";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
hardware.cpu.amd.updateMicrocode = true;
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
system.stateVersion = "22.05";
|
||||||
|
}
|
|
@ -1,843 +0,0 @@
|
||||||
# This module provides configuration for the PAM (Pluggable
|
|
||||||
# Authentication Modules) system.
|
|
||||||
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
pam_p11 = pkgs.callPackage ./pam_p11.nix {};
|
|
||||||
|
|
||||||
parentConfig = config;
|
|
||||||
|
|
||||||
pamOpts = { config, name, ... }: let cfg = config; in let config = parentConfig; in {
|
|
||||||
|
|
||||||
options = {
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
example = "sshd";
|
|
||||||
type = types.str;
|
|
||||||
description = "Name of the PAM service.";
|
|
||||||
};
|
|
||||||
|
|
||||||
unixAuth = mkOption {
|
|
||||||
default = true;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Whether users can log in with passwords defined in
|
|
||||||
<filename>/etc/shadow</filename>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
rootOK = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, root doesn't need to authenticate (e.g. for the
|
|
||||||
<command>useradd</command> service).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
p11Auth = mkOption {
|
|
||||||
default = config.security.pam.p11.enable;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, keys listed in
|
|
||||||
<filename>~/.ssh/authorized_keys</filename> and
|
|
||||||
<filename>~/.eid/authorized_certificates</filename>
|
|
||||||
can be used to log in with the associated PKCS#11 tokens.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
u2fAuth = mkOption {
|
|
||||||
default = config.security.pam.u2f.enable;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, users listed in
|
|
||||||
<filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
|
|
||||||
<filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
|
|
||||||
not set) are able to log in with the associated U2F key. Path can be
|
|
||||||
changed using <option>security.pam.u2f.authFile</option> option.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
yubicoAuth = mkOption {
|
|
||||||
default = config.security.pam.yubico.enable;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, users listed in
|
|
||||||
<filename>~/.yubico/authorized_yubikeys</filename>
|
|
||||||
are able to log in with the associated Yubikey tokens.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
googleAuthenticator = {
|
|
||||||
enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, users with enabled Google Authenticator (created
|
|
||||||
<filename>~/.google_authenticator</filename>) will be required
|
|
||||||
to provide Google Authenticator token to log in.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
usbAuth = mkOption {
|
|
||||||
default = config.security.pam.usb.enable;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, users listed in
|
|
||||||
<filename>/etc/pamusb.conf</filename> are able to log in
|
|
||||||
with the associated USB key.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
otpwAuth = mkOption {
|
|
||||||
default = config.security.pam.enableOTPW;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, the OTPW system will be used (if
|
|
||||||
<filename>~/.otpw</filename> exists).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
googleOsLoginAccountVerification = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, will use the Google OS Login PAM modules
|
|
||||||
(<literal>pam_oslogin_login</literal>,
|
|
||||||
<literal>pam_oslogin_admin</literal>) to verify possible OS Login
|
|
||||||
users and set sudoers configuration accordingly.
|
|
||||||
This only makes sense to enable for the <literal>sshd</literal> PAM
|
|
||||||
service.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
googleOsLoginAuthentication = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, will use the <literal>pam_oslogin_login</literal>'s user
|
|
||||||
authentication methods to authenticate users using 2FA.
|
|
||||||
This only makes sense to enable for the <literal>sshd</literal> PAM
|
|
||||||
service.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
fprintAuth = mkOption {
|
|
||||||
default = config.services.fprintd.enable;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, fingerprint reader will be used (if exists and
|
|
||||||
your fingerprints are enrolled).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
oathAuth = mkOption {
|
|
||||||
default = config.security.pam.oath.enable;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, the OATH Toolkit will be used.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sshAgentAuth = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, the calling user's SSH agent is used to authenticate
|
|
||||||
against the keys in the calling user's
|
|
||||||
<filename>~/.ssh/authorized_keys</filename>. This is useful
|
|
||||||
for <command>sudo</command> on password-less remote systems.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
duoSecurity = {
|
|
||||||
enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, use the Duo Security pam module
|
|
||||||
<literal>pam_duo</literal> for authentication. Requires
|
|
||||||
configuration of <option>security.duosec</option> options.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
startSession = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If set, the service will register a new session with
|
|
||||||
systemd's login manager. For local sessions, this will give
|
|
||||||
the user access to audio devices, CD-ROM drives. In the
|
|
||||||
default PolicyKit configuration, it also allows the user to
|
|
||||||
reboot the system.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
setEnvironment = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Whether the service should set the environment variables
|
|
||||||
listed in <option>environment.sessionVariables</option>
|
|
||||||
using <literal>pam_env.so</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
setLoginUid = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Set the login uid of the process
|
|
||||||
(<filename>/proc/self/loginuid</filename>) for auditing
|
|
||||||
purposes. The login uid is only set by ‘entry points’ like
|
|
||||||
<command>login</command> and <command>sshd</command>, not by
|
|
||||||
commands like <command>sudo</command>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
forwardXAuth = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Whether X authentication keys should be passed from the
|
|
||||||
calling user to the target user (e.g. for
|
|
||||||
<command>su</command>)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
pamMount = mkOption {
|
|
||||||
default = config.security.pam.mount.enable;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Enable PAM mount (pam_mount) system to mount fileystems on user login.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
allowNullPassword = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Whether to allow logging into accounts that have no password
|
|
||||||
set (i.e., have an empty password field in
|
|
||||||
<filename>/etc/passwd</filename> or
|
|
||||||
<filename>/etc/group</filename>). This does not enable
|
|
||||||
logging into disabled accounts (i.e., that have the password
|
|
||||||
field set to <literal>!</literal>). Note that regardless of
|
|
||||||
what the pam_unix documentation says, accounts with hashed
|
|
||||||
empty passwords are always allowed to log in.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
nodelay = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Wheather the delay after typing a wrong password should be disabled.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
requireWheel = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Whether to permit root access only to members of group wheel.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
limits = mkOption {
|
|
||||||
description = ''
|
|
||||||
Attribute set describing resource limits. Defaults to the
|
|
||||||
value of <option>security.pam.loginLimits</option>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
showMotd = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = "Whether to show the message of the day.";
|
|
||||||
};
|
|
||||||
|
|
||||||
makeHomeDir = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Whether to try to create home directories for users
|
|
||||||
with <literal>$HOME</literal>s pointing to nonexistent
|
|
||||||
locations on session login.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
updateWtmp = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = "Whether to update <filename>/var/log/wtmp</filename>.";
|
|
||||||
};
|
|
||||||
|
|
||||||
logFailures = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = "Whether to log authentication failures in <filename>/var/log/faillog</filename>.";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableAppArmor = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Enable support for attaching AppArmor profiles at the
|
|
||||||
user/group level, e.g., as part of a role based access
|
|
||||||
control scheme.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
enableKwallet = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If enabled, pam_wallet will attempt to automatically unlock the
|
|
||||||
user's default KDE wallet upon login. If the user has no wallet named
|
|
||||||
"kdewallet", or the login password does not match their wallet
|
|
||||||
password, KDE will prompt separately after login.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
sssdStrictAccess = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = "enforce sssd access control";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableGnomeKeyring = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
If enabled, pam_gnome_keyring will attempt to automatically unlock the
|
|
||||||
user's default Gnome keyring upon login. If the user login password does
|
|
||||||
not match their keyring password, Gnome Keyring will prompt separately
|
|
||||||
after login.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
text = mkOption {
|
|
||||||
type = types.nullOr types.lines;
|
|
||||||
description = "Contents of the PAM service file.";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
name = mkDefault name;
|
|
||||||
setLoginUid = mkDefault cfg.startSession;
|
|
||||||
limits = mkDefault config.security.pam.loginLimits;
|
|
||||||
|
|
||||||
# !!! TODO: move the LDAP stuff to the LDAP module, and the
|
|
||||||
# Samba stuff to the Samba module. This requires that the PAM
|
|
||||||
# module provides the right hooks.
|
|
||||||
text = mkDefault
|
|
||||||
(''
|
|
||||||
# Account management.
|
|
||||||
account required pam_unix.so
|
|
||||||
${optionalString use_ldap
|
|
||||||
"account sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
|
|
||||||
${optionalString (config.services.sssd.enable && cfg.sssdStrictAccess==false)
|
|
||||||
"account sufficient ${pkgs.sssd}/lib/security/pam_sss.so"}
|
|
||||||
${optionalString (config.services.sssd.enable && cfg.sssdStrictAccess)
|
|
||||||
"account [default=bad success=ok user_unknown=ignore] ${pkgs.sssd}/lib/security/pam_sss.so"}
|
|
||||||
${optionalString config.krb5.enable
|
|
||||||
"account sufficient ${pam_krb5}/lib/security/pam_krb5.so"}
|
|
||||||
${optionalString cfg.googleOsLoginAccountVerification ''
|
|
||||||
account [success=ok ignore=ignore default=die] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so
|
|
||||||
account [success=ok default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so
|
|
||||||
''}
|
|
||||||
|
|
||||||
# Authentication management.
|
|
||||||
${optionalString cfg.googleOsLoginAuthentication
|
|
||||||
"auth [success=done perm_denied=bad default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so"}
|
|
||||||
${optionalString cfg.rootOK
|
|
||||||
"auth sufficient pam_rootok.so"}
|
|
||||||
${optionalString cfg.requireWheel
|
|
||||||
"auth required pam_wheel.so use_uid"}
|
|
||||||
${optionalString cfg.logFailures
|
|
||||||
"auth required pam_tally.so"}
|
|
||||||
${optionalString (config.security.pam.enableSSHAgentAuth && cfg.sshAgentAuth)
|
|
||||||
"auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys:~/.ssh/authorized_keys2:/etc/ssh/authorized_keys.d/%u"}
|
|
||||||
${optionalString cfg.fprintAuth
|
|
||||||
"auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so"}
|
|
||||||
${let p11 = config.security.pam.p11; in optionalString cfg.p11Auth
|
|
||||||
"auth ${p11.control} ${pam_p11}/lib/security/pam_p11.so ${pkgs.opensc}/lib/opensc-pkcs11.so"}
|
|
||||||
${let u2f = config.security.pam.u2f; in optionalString cfg.u2fAuth
|
|
||||||
"auth ${u2f.control} ${pkgs.pam_u2f}/lib/security/pam_u2f.so ${optionalString u2f.debug "debug"} ${optionalString (u2f.authFile != null) "authfile=${u2f.authFile}"} ${optionalString u2f.interactive "interactive"} ${optionalString u2f.cue "cue"}"}
|
|
||||||
${optionalString cfg.usbAuth
|
|
||||||
"auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"}
|
|
||||||
${let oath = config.security.pam.oath; in optionalString cfg.oathAuth
|
|
||||||
"auth requisite ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits}"}
|
|
||||||
${let yubi = config.security.pam.yubico; in optionalString cfg.yubicoAuth
|
|
||||||
"auth ${yubi.control} ${pkgs.yubico-pam}/lib/security/pam_yubico.so mode=${toString yubi.mode} ${optionalString (yubi.mode == "client") "id=${toString yubi.id}"} ${optionalString yubi.debug "debug"}"}
|
|
||||||
'' +
|
|
||||||
# Modules in this block require having the password set in PAM_AUTHTOK.
|
|
||||||
# pam_unix is marked as 'sufficient' on NixOS which means nothing will run
|
|
||||||
# after it succeeds. Certain modules need to run after pam_unix
|
|
||||||
# prompts the user for password so we run it once with 'required' at an
|
|
||||||
# earlier point and it will run again with 'sufficient' further down.
|
|
||||||
# We use try_first_pass the second time to avoid prompting password twice
|
|
||||||
(optionalString (cfg.unixAuth &&
|
|
||||||
(config.security.pam.enableEcryptfs
|
|
||||||
|| cfg.pamMount
|
|
||||||
|| cfg.enableKwallet
|
|
||||||
|| cfg.enableGnomeKeyring
|
|
||||||
|| cfg.googleAuthenticator.enable
|
|
||||||
|| cfg.duoSecurity.enable)) ''
|
|
||||||
auth required pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} ${optionalString cfg.nodelay "nodelay"} likeauth
|
|
||||||
${optionalString config.security.pam.enableEcryptfs
|
|
||||||
"auth optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
|
|
||||||
${optionalString cfg.pamMount
|
|
||||||
"auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
|
|
||||||
${optionalString cfg.enableKwallet
|
|
||||||
("auth optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
|
||||||
" kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
|
|
||||||
${optionalString cfg.enableGnomeKeyring
|
|
||||||
"auth optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so"}
|
|
||||||
${optionalString cfg.googleAuthenticator.enable
|
|
||||||
"auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp"}
|
|
||||||
${optionalString cfg.duoSecurity.enable
|
|
||||||
"auth required ${pkgs.duo-unix}/lib/security/pam_duo.so"}
|
|
||||||
'') + ''
|
|
||||||
${optionalString cfg.unixAuth
|
|
||||||
"auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} ${optionalString cfg.nodelay "nodelay"} likeauth try_first_pass"}
|
|
||||||
${optionalString cfg.otpwAuth
|
|
||||||
"auth sufficient ${pkgs.otpw}/lib/security/pam_otpw.so"}
|
|
||||||
${optionalString use_ldap
|
|
||||||
"auth sufficient ${pam_ldap}/lib/security/pam_ldap.so use_first_pass"}
|
|
||||||
${optionalString config.services.sssd.enable
|
|
||||||
"auth sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_first_pass"}
|
|
||||||
${optionalString config.krb5.enable ''
|
|
||||||
auth [default=ignore success=1 service_err=reset] ${pam_krb5}/lib/security/pam_krb5.so use_first_pass
|
|
||||||
auth [default=die success=done] ${pam_ccreds}/lib/security/pam_ccreds.so action=validate use_first_pass
|
|
||||||
auth sufficient ${pam_ccreds}/lib/security/pam_ccreds.so action=store use_first_pass
|
|
||||||
''}
|
|
||||||
auth required pam_deny.so
|
|
||||||
|
|
||||||
# Password management.
|
|
||||||
password sufficient pam_unix.so nullok sha512
|
|
||||||
${optionalString config.security.pam.enableEcryptfs
|
|
||||||
"password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
|
|
||||||
${optionalString cfg.pamMount
|
|
||||||
"password optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
|
|
||||||
${optionalString use_ldap
|
|
||||||
"password sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
|
|
||||||
${optionalString config.services.sssd.enable
|
|
||||||
"password sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_authtok"}
|
|
||||||
${optionalString config.krb5.enable
|
|
||||||
"password sufficient ${pam_krb5}/lib/security/pam_krb5.so use_first_pass"}
|
|
||||||
${optionalString config.services.samba.syncPasswordsByPam
|
|
||||||
"password optional ${pkgs.samba}/lib/security/pam_smbpass.so nullok use_authtok try_first_pass"}
|
|
||||||
${optionalString cfg.enableGnomeKeyring
|
|
||||||
"password optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so use_authtok"}
|
|
||||||
|
|
||||||
# Session management.
|
|
||||||
${optionalString cfg.setEnvironment ''
|
|
||||||
session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0
|
|
||||||
''}
|
|
||||||
session required pam_unix.so
|
|
||||||
${optionalString cfg.setLoginUid
|
|
||||||
"session ${
|
|
||||||
if config.boot.isContainer then "optional" else "required"
|
|
||||||
} pam_loginuid.so"}
|
|
||||||
${optionalString cfg.makeHomeDir
|
|
||||||
"session required ${pkgs.pam}/lib/security/pam_mkhomedir.so silent skel=${config.security.pam.makeHomeDir.skelDirectory} umask=0022"}
|
|
||||||
${optionalString cfg.updateWtmp
|
|
||||||
"session required ${pkgs.pam}/lib/security/pam_lastlog.so silent"}
|
|
||||||
${optionalString config.security.pam.enableEcryptfs
|
|
||||||
"session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
|
|
||||||
${optionalString use_ldap
|
|
||||||
"session optional ${pam_ldap}/lib/security/pam_ldap.so"}
|
|
||||||
${optionalString config.services.sssd.enable
|
|
||||||
"session optional ${pkgs.sssd}/lib/security/pam_sss.so"}
|
|
||||||
${optionalString config.krb5.enable
|
|
||||||
"session optional ${pam_krb5}/lib/security/pam_krb5.so"}
|
|
||||||
${optionalString cfg.otpwAuth
|
|
||||||
"session optional ${pkgs.otpw}/lib/security/pam_otpw.so"}
|
|
||||||
${optionalString cfg.startSession
|
|
||||||
"session optional ${pkgs.systemd}/lib/security/pam_systemd.so"}
|
|
||||||
${optionalString cfg.forwardXAuth
|
|
||||||
"session optional pam_xauth.so xauthpath=${pkgs.xorg.xauth}/bin/xauth systemuser=99"}
|
|
||||||
${optionalString (cfg.limits != [])
|
|
||||||
"session required ${pkgs.pam}/lib/security/pam_limits.so conf=${makeLimitsConf cfg.limits}"}
|
|
||||||
${optionalString (cfg.showMotd && config.users.motd != null)
|
|
||||||
"session optional ${pkgs.pam}/lib/security/pam_motd.so motd=${motd}"}
|
|
||||||
${optionalString cfg.pamMount
|
|
||||||
"session optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
|
|
||||||
${optionalString (cfg.enableAppArmor && config.security.apparmor.enable)
|
|
||||||
"session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug"}
|
|
||||||
${optionalString (cfg.enableKwallet)
|
|
||||||
("session optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
|
||||||
" kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
|
|
||||||
${optionalString (cfg.enableGnomeKeyring)
|
|
||||||
"session optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start"}
|
|
||||||
${optionalString (config.virtualisation.lxc.lxcfs.enable)
|
|
||||||
"session optional ${pkgs.lxc}/lib/security/pam_cgfs.so -c all"}
|
|
||||||
'');
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inherit (pkgs) pam_krb5 pam_ccreds;
|
|
||||||
|
|
||||||
use_ldap = (config.users.ldap.enable && config.users.ldap.loginPam);
|
|
||||||
pam_ldap = if config.users.ldap.daemon.enable then pkgs.nss_pam_ldapd else pkgs.pam_ldap;
|
|
||||||
|
|
||||||
# Create a limits.conf(5) file.
|
|
||||||
makeLimitsConf = limits:
|
|
||||||
pkgs.writeText "limits.conf"
|
|
||||||
(concatMapStrings ({ domain, type, item, value }:
|
|
||||||
"${domain} ${type} ${item} ${toString value}\n")
|
|
||||||
limits);
|
|
||||||
|
|
||||||
motd = pkgs.writeText "motd" config.users.motd;
|
|
||||||
|
|
||||||
makePAMService = name: service:
|
|
||||||
{ name = "pam.d/${name}";
|
|
||||||
value.source = pkgs.writeText "${name}.pam" service.text;
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
(mkRenamedOptionModule [ "security" "pam" "enableU2F" ] [ "security" "pam" "u2f" "enable" ])
|
|
||||||
];
|
|
||||||
|
|
||||||
###### interface
|
|
||||||
|
|
||||||
options = {
|
|
||||||
|
|
||||||
security.pam.loginLimits = mkOption {
|
|
||||||
default = [];
|
|
||||||
example =
|
|
||||||
[ { domain = "ftp";
|
|
||||||
type = "hard";
|
|
||||||
item = "nproc";
|
|
||||||
value = "0";
|
|
||||||
}
|
|
||||||
{ domain = "@student";
|
|
||||||
type = "-";
|
|
||||||
item = "maxlogins";
|
|
||||||
value = "4";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
description =
|
|
||||||
'' Define resource limits that should apply to users or groups.
|
|
||||||
Each item in the list should be an attribute set with a
|
|
||||||
<varname>domain</varname>, <varname>type</varname>,
|
|
||||||
<varname>item</varname>, and <varname>value</varname>
|
|
||||||
attribute. The syntax and semantics of these attributes
|
|
||||||
must be that described in the limits.conf(5) man page.
|
|
||||||
|
|
||||||
Note that these limits do not apply to systemd services,
|
|
||||||
whose limits can be changed via <option>systemd.extraConfig</option>
|
|
||||||
instead.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
security.pam.services = mkOption {
|
|
||||||
default = [];
|
|
||||||
type = with types; loaOf (submodule pamOpts);
|
|
||||||
description =
|
|
||||||
''
|
|
||||||
This option defines the PAM services. A service typically
|
|
||||||
corresponds to a program that uses PAM,
|
|
||||||
e.g. <command>login</command> or <command>passwd</command>.
|
|
||||||
Each attribute of this set defines a PAM service, with the attribute name
|
|
||||||
defining the name of the service.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
security.pam.makeHomeDir.skelDirectory = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/var/empty";
|
|
||||||
example = "/etc/skel";
|
|
||||||
description = ''
|
|
||||||
Path to skeleton directory whose contents are copied to home
|
|
||||||
directories newly created by <literal>pam_mkhomedir</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
security.pam.enableSSHAgentAuth = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description =
|
|
||||||
''
|
|
||||||
Enable sudo logins if the user's SSH agent provides a key
|
|
||||||
present in <filename>~/.ssh/authorized_keys</filename>.
|
|
||||||
This allows machines to exclusively use SSH keys instead of
|
|
||||||
passwords.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
security.pam.enableOTPW = mkEnableOption "the OTPW (one-time password) PAM module";
|
|
||||||
|
|
||||||
security.pam.p11 = {
|
|
||||||
enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Enables P11 PAM (<literal>pam_p11</literal>) module.
|
|
||||||
|
|
||||||
If set, users can log in with SSH keys and PKCS#11 tokens.
|
|
||||||
|
|
||||||
More information can be found <link
|
|
||||||
xlink:href="https://github.com/OpenSC/pam_p11">here</link>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
control = mkOption {
|
|
||||||
default = "sufficient";
|
|
||||||
type = types.enum [ "required" "requisite" "sufficient" "optional" ];
|
|
||||||
description = ''
|
|
||||||
This option sets pam "control".
|
|
||||||
If you want to have multi factor authentication, use "required".
|
|
||||||
If you want to use the PKCS#11 device instead of the regular password,
|
|
||||||
use "sufficient".
|
|
||||||
|
|
||||||
Read
|
|
||||||
<citerefentry>
|
|
||||||
<refentrytitle>pam.conf</refentrytitle>
|
|
||||||
<manvolnum>5</manvolnum>
|
|
||||||
</citerefentry>
|
|
||||||
for better understanding of this option.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
security.pam.u2f = {
|
|
||||||
enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Enables U2F PAM (<literal>pam-u2f</literal>) module.
|
|
||||||
|
|
||||||
If set, users listed in
|
|
||||||
<filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
|
|
||||||
<filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
|
|
||||||
not set) are able to log in with the associated U2F key. The path can
|
|
||||||
be changed using <option>security.pam.u2f.authFile</option> option.
|
|
||||||
|
|
||||||
File format is:
|
|
||||||
<literal>username:first_keyHandle,first_public_key: second_keyHandle,second_public_key</literal>
|
|
||||||
This file can be generated using <command>pamu2fcfg</command> command.
|
|
||||||
|
|
||||||
More information can be found <link
|
|
||||||
xlink:href="https://developers.yubico.com/pam-u2f/">here</link>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
authFile = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = with types; nullOr path;
|
|
||||||
description = ''
|
|
||||||
By default <literal>pam-u2f</literal> module reads the keys from
|
|
||||||
<filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
|
|
||||||
<filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
|
|
||||||
not set).
|
|
||||||
|
|
||||||
If you want to change auth file locations or centralize database (for
|
|
||||||
example use <filename>/etc/u2f-mappings</filename>) you can set this
|
|
||||||
option.
|
|
||||||
|
|
||||||
File format is:
|
|
||||||
<literal>username:first_keyHandle,first_public_key: second_keyHandle,second_public_key</literal>
|
|
||||||
This file can be generated using <command>pamu2fcfg</command> command.
|
|
||||||
|
|
||||||
More information can be found <link
|
|
||||||
xlink:href="https://developers.yubico.com/pam-u2f/">here</link>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
control = mkOption {
|
|
||||||
default = "sufficient";
|
|
||||||
type = types.enum [ "required" "requisite" "sufficient" "optional" ];
|
|
||||||
description = ''
|
|
||||||
This option sets pam "control".
|
|
||||||
If you want to have multi factor authentication, use "required".
|
|
||||||
If you want to use U2F device instead of regular password, use "sufficient".
|
|
||||||
|
|
||||||
Read
|
|
||||||
<citerefentry>
|
|
||||||
<refentrytitle>pam.conf</refentrytitle>
|
|
||||||
<manvolnum>5</manvolnum>
|
|
||||||
</citerefentry>
|
|
||||||
for better understanding of this option.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
debug = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Debug output to stderr.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
interactive = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Set to prompt a message and wait before testing the presence of a U2F device.
|
|
||||||
Recommended if your device doesn’t have a tactile trigger.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
cue = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
By default <literal>pam-u2f</literal> module does not inform user
|
|
||||||
that he needs to use the u2f device, it just waits without a prompt.
|
|
||||||
|
|
||||||
If you set this option to <literal>true</literal>,
|
|
||||||
<literal>cue</literal> option is added to <literal>pam-u2f</literal>
|
|
||||||
module and reminder message will be displayed.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
security.pam.yubico = {
|
|
||||||
enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Enables Yubico PAM (<literal>yubico-pam</literal>) module.
|
|
||||||
|
|
||||||
If set, users listed in
|
|
||||||
<filename>~/.yubico/authorized_yubikeys</filename>
|
|
||||||
are able to log in with the associated Yubikey tokens.
|
|
||||||
|
|
||||||
The file must have only one line:
|
|
||||||
<literal>username:yubikey_token_id1:yubikey_token_id2</literal>
|
|
||||||
More information can be found <link
|
|
||||||
xlink:href="https://developers.yubico.com/yubico-pam/">here</link>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
control = mkOption {
|
|
||||||
default = "sufficient";
|
|
||||||
type = types.enum [ "required" "requisite" "sufficient" "optional" ];
|
|
||||||
description = ''
|
|
||||||
This option sets pam "control".
|
|
||||||
If you want to have multi factor authentication, use "required".
|
|
||||||
If you want to use Yubikey instead of regular password, use "sufficient".
|
|
||||||
|
|
||||||
Read
|
|
||||||
<citerefentry>
|
|
||||||
<refentrytitle>pam.conf</refentrytitle>
|
|
||||||
<manvolnum>5</manvolnum>
|
|
||||||
</citerefentry>
|
|
||||||
for better understanding of this option.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
id = mkOption {
|
|
||||||
example = "42";
|
|
||||||
type = types.str;
|
|
||||||
description = "client id";
|
|
||||||
};
|
|
||||||
|
|
||||||
debug = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Debug output to stderr.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
mode = mkOption {
|
|
||||||
default = "client";
|
|
||||||
type = types.enum [ "client" "challenge-response" ];
|
|
||||||
description = ''
|
|
||||||
Mode of operation.
|
|
||||||
|
|
||||||
Use "client" for online validation with a YubiKey validation service such as
|
|
||||||
the YubiCloud.
|
|
||||||
|
|
||||||
Use "challenge-response" for offline validation using YubiKeys with HMAC-SHA-1
|
|
||||||
Challenge-Response configurations. See the man-page ykpamcfg(1) for further
|
|
||||||
details on how to configure offline Challenge-Response validation.
|
|
||||||
|
|
||||||
More information can be found <link
|
|
||||||
xlink:href="https://developers.yubico.com/yubico-pam/Authentication_Using_Challenge-Response.html">here</link>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
security.pam.enableEcryptfs = mkEnableOption "eCryptfs PAM module (mounting ecryptfs home directory on login)";
|
|
||||||
|
|
||||||
users.motd = mkOption {
|
|
||||||
default = null;
|
|
||||||
example = "Today is Sweetmorn, the 4th day of The Aftermath in the YOLD 3178.";
|
|
||||||
type = types.nullOr types.lines;
|
|
||||||
description = "Message of the day shown to users when they log in.";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
###### implementation
|
|
||||||
|
|
||||||
config = {
|
|
||||||
|
|
||||||
environment.systemPackages =
|
|
||||||
# Include the PAM modules in the system path mostly for the manpages.
|
|
||||||
[ pkgs.pam ]
|
|
||||||
++ optional config.users.ldap.enable pam_ldap
|
|
||||||
++ optional config.services.sssd.enable pkgs.sssd
|
|
||||||
++ optionals config.krb5.enable [pam_krb5 pam_ccreds]
|
|
||||||
++ optionals config.security.pam.enableOTPW [ pkgs.otpw ]
|
|
||||||
++ optionals config.security.pam.oath.enable [ pkgs.oathToolkit ]
|
|
||||||
++ optionals config.security.pam.p11.enable [ pam_p11 ]
|
|
||||||
++ optionals config.security.pam.u2f.enable [ pkgs.pam_u2f ];
|
|
||||||
|
|
||||||
boot.supportedFilesystems = optionals config.security.pam.enableEcryptfs [ "ecryptfs" ];
|
|
||||||
|
|
||||||
security.wrappers = {
|
|
||||||
unix_chkpwd = {
|
|
||||||
source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
|
|
||||||
owner = "root";
|
|
||||||
setuid = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.etc = mapAttrs' makePAMService config.security.pam.services;
|
|
||||||
|
|
||||||
security.pam.services =
|
|
||||||
{ other.text =
|
|
||||||
''
|
|
||||||
auth required pam_warn.so
|
|
||||||
auth required pam_deny.so
|
|
||||||
account required pam_warn.so
|
|
||||||
account required pam_deny.so
|
|
||||||
password required pam_warn.so
|
|
||||||
password required pam_deny.so
|
|
||||||
session required pam_warn.so
|
|
||||||
session required pam_deny.so
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Most of these should be moved to specific modules.
|
|
||||||
i3lock = {};
|
|
||||||
i3lock-color = {};
|
|
||||||
vlock = {};
|
|
||||||
xlock = {};
|
|
||||||
xscreensaver = {};
|
|
||||||
|
|
||||||
runuser = { rootOK = true; unixAuth = false; setEnvironment = false; };
|
|
||||||
|
|
||||||
/* FIXME: should runuser -l start a systemd session? Currently
|
|
||||||
it complains "Cannot create session: Already running in a
|
|
||||||
session". */
|
|
||||||
runuser-l = { rootOK = true; unixAuth = false; };
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
{ stdenv, fetchFromGitHub, autoreconfHook, pkg-config, openssl, libp11, pam }:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "pam_p11";
|
|
||||||
version = "0.3.1";
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "OpenSC";
|
|
||||||
repo = "pam_p11";
|
|
||||||
rev = "pam_p11-${version}";
|
|
||||||
sha256 = "1caidy18rq5zk82d51x8vwidmkhwmanf3qm25x1yrdlbhxv6m7lk";
|
|
||||||
};
|
|
||||||
|
|
||||||
patchPhase =
|
|
||||||
''
|
|
||||||
substituteInPlace src/match_openssh.c --replace \
|
|
||||||
'"%s/.ssh/authorized_keys", pw->pw_dir)' \
|
|
||||||
'"/etc/ssh/authorized_keys.d/%s", pw->pw_name)'
|
|
||||||
'';
|
|
||||||
|
|
||||||
nativeBuildInputs = [ autoreconfHook pkg-config ];
|
|
||||||
buildInputs = [ pam openssl libp11 ];
|
|
||||||
}
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "sd_mod" "rtsx_usb_sdmmc" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/348c924c-1d86-44ff-84af-2594f414e7d0";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/1BDC-44BB";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/opt" =
|
||||||
|
{ device = "/dev/disk/by-uuid/cf0f51b6-7b95-4c74-9390-37dc4c86f32b";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlp2s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "23.11";
|
||||||
|
}
|
|
@ -1,32 +1,22 @@
|
||||||
{ host, rpi4 }:
|
{ host, rpi4, experimental-users ? false }:
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
let
|
let
|
||||||
m-labs = import (fetchTarball https://nixbld.m-labs.hk/channel/custom/artiq/full/artiq-full/nixexprs.tar.xz) { inherit pkgs; };
|
artiq = builtins.getFlake git+https://github.com/m-labs/artiq.git;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
deployment.targetHost = host;
|
deployment.targetHost = host;
|
||||||
|
deployment.hasFastConnection = true;
|
||||||
|
nix.nixPath = [ "nixpkgs=${pkgs.path}" ];
|
||||||
|
programs.command-not-found.dbPath = "${pkgs.path}/programs.sqlite";
|
||||||
nixpkgs.system = "aarch64-linux";
|
nixpkgs.system = "aarch64-linux";
|
||||||
|
|
||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
|
boot.kernelParams = if rpi4 then ["cma=64M"] else []; # work around https://github.com/raspberrypi/linux/issues/3208
|
||||||
|
boot.initrd.includeDefaultModules = false;
|
||||||
|
|
||||||
boot.loader.generic-extlinux-compatible.enable = !rpi4;
|
fileSystems = {
|
||||||
boot.loader.raspberryPi = pkgs.lib.mkIf rpi4 {
|
|
||||||
enable = true;
|
|
||||||
version = 4;
|
|
||||||
};
|
|
||||||
boot.kernelPackages = pkgs.lib.mkIf rpi4 pkgs.linuxPackages_latest;
|
|
||||||
|
|
||||||
fileSystems = if rpi4 then {
|
|
||||||
"/boot" = {
|
|
||||||
device = "/dev/disk/by-label/FIRMWARE";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
"/" = {
|
|
||||||
device = "/dev/disk/by-label/NIXOS_SD";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
"/" = {
|
"/" = {
|
||||||
device = "/dev/disk/by-label/NIXOS_SD";
|
device = "/dev/disk/by-label/NIXOS_SD";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
|
@ -34,7 +24,9 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
services.openssh.passwordAuthentication = false;
|
services.openssh.authorizedKeysInHomedir = false;
|
||||||
|
services.openssh.settings.PasswordAuthentication = false;
|
||||||
|
services.openssh.settings.GatewayPorts = "clientspecified";
|
||||||
services.openssh.extraConfig =
|
services.openssh.extraConfig =
|
||||||
''
|
''
|
||||||
StreamLocalBindUnlink yes
|
StreamLocalBindUnlink yes
|
||||||
|
@ -42,27 +34,41 @@ in
|
||||||
programs.mosh.enable = true;
|
programs.mosh.enable = true;
|
||||||
|
|
||||||
networking.hostName = host;
|
networking.hostName = host;
|
||||||
|
|
||||||
time.timeZone = "Asia/Hong_Kong";
|
time.timeZone = "Asia/Hong_Kong";
|
||||||
|
|
||||||
users.extraGroups.plugdev = { };
|
users.extraGroups.plugdev = { };
|
||||||
users.mutableUsers = false;
|
users.mutableUsers = false;
|
||||||
users.defaultUserShell = pkgs.fish;
|
users.defaultUserShell = pkgs.fish;
|
||||||
users.extraUsers = (import ./common-users.nix { inherit pkgs; }) // {
|
users.extraUsers = (import ./common-users.nix { inherit pkgs; }) // {
|
||||||
nix = {
|
nixbld = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
|
extraGroups = ["plugdev" "dialout"];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGJGICdNM9mHHAa1Cxk9Wz3YLkIEeqrIQGxM0aoy1g5O"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
security.sudo.wheelNeedsPassword = false;
|
security.sudo.wheelNeedsPassword = false;
|
||||||
services.udev.packages = [ m-labs.openocd ];
|
services.udev.packages = [ artiq.packages.aarch64-linux.openocd-bscanspi ];
|
||||||
|
services.udev.extraRules = (import ./extra-udev.nix);
|
||||||
|
|
||||||
documentation.enable = false;
|
documentation.enable = false;
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
psmisc wget vim git usbutils lm_sensors file telnet mosh tmux xc3sprog m-labs.openocd screen gdb minicom picocom
|
psmisc wget vim git sshfs usbutils uhubctl lm_sensors file mosh tmux
|
||||||
|
artiq.packages.aarch64-linux.openocd-bscanspi
|
||||||
|
xc3sprog
|
||||||
|
screen gdb minicom picocom
|
||||||
];
|
];
|
||||||
|
programs.zsh.enable = true;
|
||||||
programs.fish.enable = true;
|
programs.fish.enable = true;
|
||||||
programs.wireshark.enable = true;
|
programs.wireshark.enable = true;
|
||||||
|
|
||||||
nix.binaryCachePublicKeys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
|
nix.settings.trusted-public-keys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
|
||||||
nix.binaryCaches = ["https://cache.nixos.org" "https://nixbld.m-labs.hk"];
|
nix.settings.substituters = ["https://nixbld.m-labs.hk?priority=10"];
|
||||||
nix.trustedUsers = ["root" "nix"];
|
nix.settings.trusted-users = ["root" "sb"];
|
||||||
|
|
||||||
|
nix.extraOptions = ''
|
||||||
|
experimental-features = nix-command flakes impure-derivations
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "ahci" "nvme" "usbhid" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/51d521ec-4807-4b71-8a89-116b89f72d2e";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/877D-AF6A";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.enp86s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
system.stateVersion = "24.05";
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/disk/by-uuid/67168ae0-6448-4b40-b278-406290224b4f";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/8F4B-AD84";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "23.05";
|
||||||
|
}
|
|
@ -1,6 +1,3 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -21,13 +18,18 @@
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-uuid/91B4-E546";
|
{ device = "/dev/disk/by-uuid/91B4-E546";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
|
|
||||||
nix.maxJobs = lib.mkDefault 16;
|
nix.settings.max-jobs = lib.mkDefault 16;
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
hardware.cpu.intel.updateMicrocode = true;
|
||||||
|
|
||||||
|
system.stateVersion = "19.03";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
connections {
|
||||||
|
bypass-ipsec {
|
||||||
|
remote_addrs = 127.0.0.1
|
||||||
|
children {
|
||||||
|
bypass-isakmp-v4 {
|
||||||
|
local_ts = 0.0.0.0/0[udp/isakmp]
|
||||||
|
remote_ts = 0.0.0.0/0[udp/isakmp]
|
||||||
|
mode = pass
|
||||||
|
start_action = trap
|
||||||
|
}
|
||||||
|
bypass-isakmp-v6 {
|
||||||
|
local_ts = ::/0[udp/isakmp]
|
||||||
|
remote_ts = ::/0[udp/isakmp]
|
||||||
|
mode = pass
|
||||||
|
start_action = trap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_labs {
|
||||||
|
version = 2
|
||||||
|
encap = no
|
||||||
|
mobike = no
|
||||||
|
send_certreq = no
|
||||||
|
proposals = aes128gcm128-sha256-prfsha256-curve25519,aes128gcm128-sha256-prfsha256-ecp256
|
||||||
|
local_addrs = 103.206.98.1
|
||||||
|
remote_addrs = 94.190.212.123
|
||||||
|
local {
|
||||||
|
auth = pubkey
|
||||||
|
id = fqdn:igw0.hkg.as150788.net
|
||||||
|
pubkeys = igw0.hkg.as150788.net
|
||||||
|
}
|
||||||
|
remote {
|
||||||
|
auth = pubkey
|
||||||
|
id = fqdn:m-labs.hk
|
||||||
|
pubkeys = m-labs.hk
|
||||||
|
}
|
||||||
|
children {
|
||||||
|
con1 {
|
||||||
|
mode = transport
|
||||||
|
ah_proposals = sha256-curve25519,sha256-ecp256
|
||||||
|
esp_proposals =
|
||||||
|
local_ts = 103.206.98.1[gre]
|
||||||
|
remote_ts = 94.190.212.123[gre]
|
||||||
|
start_action = none
|
||||||
|
close_action = none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 142 KiB |
Binary file not shown.
After Width: | Height: | Size: 143 KiB |
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
Loading…
Reference in New Issue