Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

75 changed files with 1809 additions and 13011 deletions

View File

@ -1,56 +0,0 @@
{ 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";
};
};
}

View File

@ -1,18 +0,0 @@
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

View File

@ -1,14 +0,0 @@
[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

View File

@ -1,10 +0,0 @@
#!/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

View File

@ -1,10 +0,0 @@
#!/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

View File

@ -1,81 +0,0 @@
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;
}

View File

@ -1,34 +0,0 @@
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
}
}
}
}

View File

@ -1,65 +0,0 @@
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/*;
}

View File

@ -1,12 +0,0 @@
[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

View File

@ -1,14 +0,0 @@
#!/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

View File

@ -1,99 +0,0 @@
# 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
```

View File

@ -1,48 +0,0 @@
{ 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";
};
};
config = mkIf config.services.afws.enable {
systemd.services.afws = {
description = "AFWS server";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "afws";
Group = "afws";
ExecStart = "${afws}/bin/afws_server";
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 = {};
};
}

View File

@ -1,37 +1,27 @@
{ config, pkgs, lib, ... }:
with lib;
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" ''
#!${pkgs.bash}/bin/bash -p
#!${pkgs.bash}/bin/bash
set -e
umask 0077
DBDUMPDIR=`mktemp -d`
trap "rm -rf $DBDUMPDIR" EXIT
cd $DBDUMPDIR
pushd $DBDUMPDIR
${config.services.mysql.package}/bin/mysqldump --user=root --single-transaction flarum > flarum.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
${config.services.mysql.package}/bin/mysqldump --single-transaction flarum > flarum.sql
${pkgs.sudo}/bin/sudo -u mattermost ${config.services.postgresql.package}/bin/pg_dump mattermost > 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.gnutar}/bin/tar cf - --exclude "/var/lib/gitea/repositories/*/*.git/archives" /etc/nixos /var/lib/gitea flarum.sql mattermost.sql | \
${pkgs.bzip2}/bin/bzip2 | \
${pkgs.gnupg}/bin/gpg --symmetric --batch --passphrase-fd 6
${pkgs.gnupg}/bin/gpg --symmetric --batch --passphrase-file /etc/nixos/secret/backup-passphrase | \
${pkgs.rclone}/bin/rclone rcat --config /etc/nixos/secret/rclone.conf dropbox:backup-`date +%F`.tar.bz2.gpg
popd
rm -rf $DBDUMPDIR
echo Backup done
'';
cfg = config.services.mlabs-backup;
in
@ -45,20 +35,20 @@ in
};
config = mkIf cfg.enable {
users.extraGroups.backupdl = { };
users.extraUsers.backupdl = {
isNormalUser = true;
extraGroups = ["backupdl" "nextcloud"];
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCbH+l0FIBTPdUKOS9H5OOT5ro/nljKLsiCTzTzublCScdPPmCNy27ORbLgNHX5Ughlug5wr2rAIU9AexV+L71V5MeVHUWDfKgRsNIpUTtY6wpJkAP7r1ipk2kTWc/sxhrxyPea62cohmy1dOeLlwXO6U8FnsiZfYKmgjZ8wuTo6ixDB8krXsAZ8VY/bj5WFcXqeW8GF1Qjpel7HgpCpj3HIUyC63uwIyUoYe+cgnhjzNLbRYdU9Yx2iqcUCwEUX2cMdz5VX+xbLkL8CWcuiMFg6TFo+CUPFtuA/kVzHcZ4Pa3BiilL3rf7oXlIXGN12JVsN+caX7j2weVqm2b5u5eVsyDxiLx1KA37ukq92CYAAdOuKE+saMPsLuOn+Qd9B6D5oYnYgsWg460uEGgwczwOTXLAZTT5wrwRaKIE+ezKqtRP+Tz7l2IEixulyj1MUR+XpSwECZXiFJx5DGofwzxcd2kWnNOPBReDkHv0At5ZLNIrLuxFMz2L6UXbqvHwEu8= backupdl@minipc"
];
systemd.services.mlabs-backup = {
description = "M-Labs backup";
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "root";
ExecStart = "${makeBackup}";
};
};
security.wrappers.mlabs-backup = {
source = makeBackup;
setuid = true;
owner = "root";
group = "backupdl";
permissions = "g+x";
systemd.timers.mlabs-backup = {
description = "M-Labs backup";
wantedBy = [ "timers.target" ];
timerConfig.OnCalendar = "weekly";
};
};
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +0,0 @@
{
lib,
php,
fetchFromGitHub,
fetchpatch,
}:
php.buildComposerProject (finalAttrs: {
pname = "flarum";
version = "1.8.1";
src = fetchFromGitHub {
owner = "flarum";
repo = "flarum";
rev = "v${finalAttrs.version}";
hash = "sha256-kigUZpiHTM24XSz33VQYdeulG1YI5s/M02V7xue72VM=";
};
patches = [
# Add useful extensions from https://github.com/FriendsOfFlarum
# 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
];
};
})

View File

@ -1,16 +0,0 @@
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",

View File

@ -1,61 +0,0 @@
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:

View File

@ -3,7 +3,7 @@
<div class="ui stackable middle very relaxed page grid">
<div class="sixteen wide center aligned centered column">
<div>
<img class="logo" width="220" height="220" src="{{AssetUrlPrefix}}/img/logo.svg"/>
<img class="logo" src="{{AppSubUrl}}/img/gitea-lg.png" />
</div>
<div class="hero">
<h1 class="ui icon header title">

View File

@ -1,11 +0,0 @@
{{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" .}}

View File

@ -1,67 +0,0 @@
{ 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";
};
};
}

View File

@ -0,0 +1,13 @@
diff --git a/homu/git_helper.py b/homu/git_helper.py
index 0f70c69..f53fb57 100755
--- a/homu/git_helper.py
+++ b/homu/git_helper.py
@@ -7,7 +7,7 @@ SSH_KEY_FILE = os.path.join(os.path.dirname(__file__), '../cache/key')
def main():
- args = ['ssh', '-i', SSH_KEY_FILE, '-S', 'none'] + sys.argv[1:]
+ args = ['ssh', '-o', 'StrictHostKeyChecking=no', '-i', SSH_KEY_FILE, '-S', 'none'] + sys.argv[1:]
os.execvp('ssh', args)

View File

@ -0,0 +1,52 @@
{ config, pkgs, lib, ... }:
with lib;
let
homu = pkgs.callPackage ./pkg.nix {};
cfg = config.services.homu;
in
{
options.services.homu = {
enable = mkOption {
type = types.bool;
default = false;
description = "Enable the bot";
};
dbDir = mkOption {
type = types.str;
default = "/var/db/homu";
description = "Path to the database file (use the same path in config.toml)";
};
config = mkOption {
description = "Location of config.toml";
type = types.str;
};
};
config = mkIf cfg.enable {
users.users.homu = {
group = "homu";
home = cfg.dbDir;
createHome = true;
};
users.groups.homu = {};
systemd.services.homu = {
description = "Homu bot";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${homu}/bin/homu -c ${cfg.config}";
Restart = "always";
RestartSec = "5sec";
User = "homu";
Group = "homu";
};
};
};
}

View File

@ -0,0 +1,26 @@
diff --git a/homu/git_helper.py b/homu/git_helper.py
index 0f70c69..732230c 100755
--- a/homu/git_helper.py
+++ b/homu/git_helper.py
@@ -3,7 +3,7 @@
import sys
import os
-SSH_KEY_FILE = os.path.join(os.path.dirname(__file__), '../cache/key')
+SSH_KEY_FILE = os.path.expanduser("~/cache/key")
def main():
diff --git a/homu/main.py b/homu/main.py
index 16b60a2..a2e109a 100644
--- a/homu/main.py
+++ b/homu/main.py
@@ -649,7 +649,7 @@ def git_push(git_cmd, branch, state):
def init_local_git_cmds(repo_cfg, git_cfg):
- fpath = 'cache/{}/{}'.format(repo_cfg['owner'], repo_cfg['name'])
+ fpath = '{}/cache/{}/{}'.format(os.path.expanduser("~"), repo_cfg['owner'], repo_cfg['name'])
url = 'git@github.com:{}/{}.git'.format(repo_cfg['owner'], repo_cfg['name']) # noqa
if not os.path.exists(SSH_KEY_FILE):

View File

@ -0,0 +1,34 @@
{ python3Packages, python3, fetchFromGitHub, git, openssh }:
let
uritemplate_0_2_0 = python3Packages.github3_py.overrideAttrs(oa: rec {
version = "0.2.0";
src = python3Packages.fetchPypi {
pname = "uritemplate.py";
inherit version;
sha256 = "1pfk04pmnysz0383lwzgig8zqlwiv2n4pmq51f0mc60zz1jimq4g";
};
});
github3_py_0_9_6 = python3Packages.github3_py.overrideAttrs(oa: rec {
version = "0.9.6";
src = python3Packages.fetchPypi {
pname = "github3.py";
inherit version;
sha256 = "1i8xnh586z4kka7pjl7cy08fmzjs14c8jdp8ykb9jjpzsy2xncdq";
};
propagatedBuildInputs = [ python3Packages.requests uritemplate_0_2_0 ];
});
in
python3Packages.buildPythonApplication {
name = "homu";
src = fetchFromGitHub {
owner = "servo";
repo = "homu";
rev = "2ea53e76ebac3e5fa11bc39054b3cd4c42eff607";
sha256 = "1ih7s8zfbpq0qb9vqbxzr0r4s9ff52l4ipr916kwbck3ygliq3r9";
};
patches = [ ./patch-cache-directory.patch ./disable-ssh-host-keycheck.patch ];
postInstall = "chmod 755 $out/${python3.sitePackages}/homu/git_helper.py";
propagatedBuildInputs = [ github3_py_0_9_6 git openssh ] ++ (with python3Packages; [ toml jinja2 requests bottle waitress retrying ]);
checkPhase = "python -m unittest discover tests -v";
}

View File

@ -1,122 +0,0 @@
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>

View File

@ -1,32 +0,0 @@
diff --git src/lib/Hydra/Controller/Root.pm src/lib/Hydra/Controller/Root.pm
index a9b0d558..71869ba0 100644
--- a/src/lib/Hydra/Controller/Root.pm
+++ b/src/lib/Hydra/Controller/Root.pm
@@ -19,6 +19,11 @@ use Net::Prometheus;
# Put this controller at top-level.
__PACKAGE__->config->{namespace} = '';
+sub isRedistRestricted {
+ my ($path) = @_;
+
+ return index($path, "-RESTRICTDIST-") >= 0;
+}
sub noLoginNeeded {
my ($c) = @_;
@@ -319,6 +324,7 @@ sub nar :Local :Args(1) {
$path = $Nix::Config::storeDir . "/$path";
gone($c, "Path " . $path . " is no longer available.") unless isValidPath($path);
+ notFound($c, "Redistribution restricted") if isRedistRestricted($path);
$c->stash->{current_view} = 'NixNAR';
$c->stash->{storePath} = $path;
@@ -368,6 +374,7 @@ sub narinfo :LocalRegex('^([a-z0-9]+).narinfo$') :Args(0) {
setCacheHeaders($c, 60 * 60);
return;
}
+ notFound($c, "Redistribution restricted") if isRedistRestricted($path);
$c->stash->{storePath} = $path;
$c->forward('Hydra::View::NARInfo');

View File

@ -0,0 +1,19 @@
commit 86bf81c0b8a51bffa4b4b566e1caaac6f0e041d3
Author: Sebastien Bourdeauducq <sb@m-labs.hk>
Date: Thu Mar 14 17:45:32 2019 +0800
add option to disable retries on transient failures
diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc
index 69c430eb..bdbc808d 100644
--- a/src/hydra-queue-runner/build-remote.cc
+++ b/src/hydra-queue-runner/build-remote.cc
@@ -344,7 +344,7 @@ void State::buildRemote(ref<Store> destStore,
break;
case BuildResult::TransientFailure:
result.stepStatus = bsFailed;
- result.canRetry = true;
+ result.canRetry = get(step->drv->env, "__hydraRetry").value_or("1") == "1";
result.errorMsg = "";
break;
case BuildResult::TimedOut:

View File

@ -0,0 +1,25 @@
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 = ();

View File

@ -1,29 +0,0 @@
$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 @

View File

@ -1,20 +0,0 @@
$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.

View File

@ -1,30 +0,0 @@
$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 @

View File

@ -1,53 +0,0 @@
$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

View File

@ -1,28 +0,0 @@
$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 @

View File

@ -1,23 +0,0 @@
$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"

View File

@ -1,80 +0,0 @@
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. Dont 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.
*/

View File

@ -14,13 +14,6 @@ from werkzeug.middleware.proxy_fix import ProxyFix
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.config.update(
DEBUG=getenv("FLASK_DEBUG") == "True",
@ -29,7 +22,7 @@ app.config.update(
MAIL_USE_SSL=getenv("FLASK_MAIL_USE_SSL"),
MAIL_DEBUG=False,
MAIL_USERNAME=getenv("FLASK_MAIL_USERNAME"),
MAIL_PASSWORD=mail_password,
MAIL_PASSWORD=getenv("FLASK_MAIL_PASSWORD"),
MAIL_RECIPIENT=getenv("FLASK_MAIL_RECIPIENT"),
MAIL_SENDER=getenv("FLASK_MAIL_SENDER")
)

View File

@ -7,13 +7,13 @@ in {
pythonPackages = self: [ pkg ];
module = "rfq:app";
env = [
"FLASK_MAIL_SERVER=mail.m-labs.hk"
"FLASK_MAIL_SERVER=ssl.serverraum.org"
"FLASK_MAIL_PORT=465"
"FLASK_MAIL_USE_SSL=True"
"FLASK_MAIL_USERNAME=sysop@m-labs.hk"
"FLASK_MAIL_PASSWORD_FILE=/etc/nixos/secret/rfqpassword"
"FLASK_MAIL_USERNAME=sales@m-labs.hk"
"FLASK_MAIL_PASSWORD=${import /etc/nixos/secret/sales_password.nix}"
"FLASK_MAIL_RECIPIENT=sales@m-labs.hk"
"FLASK_MAIL_SENDER=sysop@m-labs.hk"
"FLASK_MAIL_SENDER=sales@m-labs.hk"
];
socket = "${config.services.uwsgi.runDir}/uwsgi-rfq.sock";
# allow access from nginx

View File

@ -1,11 +0,0 @@
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;

View File

@ -1,298 +0,0 @@
# 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 -"
];
});
}

View File

@ -1,11 +1,11 @@
-rw------- 1 root root backup-passphrase
-rw------- 1 root root email_accounts.nix
-rw------- 1 root root gitea_tokens.nix
-rw------- 1 root root github_tokens.nix
-rw------- 1 homu homu homu.toml
-rw-rw---- 1 gitea gitea mailerpassword
-rw------- 1 matterbridge matterbridge matterbridge.toml
-rw------- 1 uwsgi uwsgi mattermost-github-integration.py
-rw------- 1 nginx nginx muninpasswd
-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 sb users wifi_ext_password.nix

View File

@ -1,45 +0,0 @@
# 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";
}

View File

@ -1,45 +0,0 @@
{ 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";
};
};
}

View File

@ -1,3 +1,6 @@
# 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, ... }:
{
@ -18,18 +21,13 @@
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/060C-8772";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices = [ ];
nix.settings.max-jobs = lib.mkDefault 16;
nix.maxJobs = lib.mkDefault 16;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
hardware.cpu.intel.updateMicrocode = true;
system.stateVersion = "19.03";
}

View File

@ -0,0 +1,29 @@
{ 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"];
}

View File

@ -1,17 +1,11 @@
{ 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 = {
isNormalUser = true;
extraGroups = ["wheel" "plugdev" "dialout" "libvirtd"];
extraGroups = ["wheel" "plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF/YybP+fQ0J+bNqM5Vgx5vDmVqVWsgUdF1moUxghv7d73GZAFaM6IFBdrXTAa33AwnWwDPMrTgP1V6SXBkb3ciJo/lD1urJGbydbSI5Ksq9d59wvOeANvyWYrQw6+eqTQ=="
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyPk5WyFoWSvF4ozehxcVBoZ+UHgrI7VW/OoQfFFwIQe0qvetUZBMZwR2FwkLPAMZV8zz1v4EfncudEkVghy4P+/YVLlDjqDq9zwZnh8Nd/ifu84wmcNWHT2UcqnhjniCdshL8a44memzABnxfLLv+sXhP2x32cJAamo5y6fukr2qLp2jbXzR+3sv3klE0ruUXis/BR1lLqNJEYP8jB6fLn2sLKinnZPfn6DwVOk10mGeQsdME/eGl3phpjhODH9JW5V2V5nJBbC0rBnq+78dyArKVqjPSmIcSy72DEIpTctnMEN1W34BGrnsDd5Xd/DKxKxHKTMCHtZRwLC2X0NWN"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMALVC8RDTHec+PC8y1s3tcpUAODgq6DEzQdHDf/cyvDMfmCaPiMxfIdmkns5lMa03hymIfSmLUF0jFFDc7biRp7uf9AAXNsrTmplHii0l0McuOOZGlSdZM4eL817P7UwJqFMxJyFXDjkubhQiX6kp25Kfuj/zLnupRCaiDvE7ho/xay6Jrv0XLz935TPDwkc7W1asLIvsZLheB+sRz9SMOb9gtrvk5WXZl5JTOFOLu+JaRwQLHL/xdcHJTOod7tqHYfpoC5JHrEwKzbhTOwxZBQBfTQjQktKENQtBxXHTe71rUEWfEZQGg60/BC4BrRmh4qJjlJu3v4VIhC7SSHn1"
];
};
@ -25,12 +19,26 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMUaB2G1jexxfkdlly3fdWslH54/s/bOuvk9AxqpjtAY robert-jordens-ed25519"
];
};
guest = {
harry = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout" "wireshark"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDcPNCgtdz8erFPRrAwCr4JrkeYXJUUvoRBgP0X2HlzJgDe1Inuo6sC6CGcO3IXbf4MwVA9XEp8BYPHARVeEHhufg/0wnIABLx2GcK99yxOLDUe4h/3YwtqvOcqHEsDx7w=="
];
};
astro = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPsv4UMEFV0UHeHdA9R3sC+qoMxrqhcuFqwqWMI4AF/lixwcbRyA8QKiu/7R22m2u6pp+Zk6hYqcxdgClI4uN2oQhVjJX6wEgfT94vC/67OKJI/NNVsR8G0lr0ufCo4Lbw=="
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGJJTSJdpDh82486uPiMhhyhnci4tScp5uUe7156MBC8 a"
];
shell = pkgs.bashInteractive;
};
pca006132 = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE/sPOOiw3843+rrcYV2pOVkffNc1xsOgnuCUmy1Fa2VF8x9kqmgQv61sxsuKRkKKoinvqrASxLkWVd6nkiiDuEISibEXs8r1BwuT05cS7RkEhCakSMZ6y/iqOtjt2bx+A=="
];
};
occheung = {
@ -40,83 +48,11 @@
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPEvmWmxpFpMgp5fpjKud8ev0cyf/+X5fEpQt/YD/+u4mbvZYPE300DLqQ0h/qjgvaGMz1ndf4idYnRdy+plJEC/+hmlRW5NlcpAr3S/LYAisacgKToFVl+MlBo+emS9Ig=="
];
};
spaqin = {
dsleung = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"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=="
];
};
esavkin = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout" "libvirtd" "wireshark"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBLDJI4GFLBmScbeR8Jh4Gi8A/2nuGlYtFTJVT+Es/bzdiPRk8DLG62T0hyRR+8LfHjbrCsDuYFNztT8hHGXd7h3xp3y2X7ArkJo8xUK5QxGd5D2Zn4ANfZTTVkoGlEHbFA=="
];
};
flo = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"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 = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGChLocYJi8XcSJkIjT2Olm3jPGjtRq5aORa5G9F3OqmjCfvav9Q5+2Mc64XqHtNTffnJuDe4gv+lVJatC0URvPs2HyxXmxRK0jgkkLSUsV2SYLlgMqHW3jsrdh6wKBmkg=="
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDbE7HzZKSwGbgRnzwrzCzb3gZKLSritwnEpHS4sa9oXJ5oLFkuFZOpPYDeiMlbUJ9jCk5FRmkLYIkrbz06SUr7P/eUjxu79ENi3RhfVu+ZrrPvgkhKvM/CiXvw3xCOu0w=="
];
};
}

View File

@ -1,46 +0,0 @@
# 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";
}

View File

@ -2,47 +2,20 @@
{ config, pkgs, ... }:
let
artiq = builtins.getFlake git+https://github.com/m-labs/artiq.git;
m-labs = import (fetchTarball https://nixbld.m-labs.hk/channel/custom/artiq/full/artiq-full/nixexprs.tar.xz) { inherit pkgs; };
pkgs-unstable = import (fetchTarball https://github.com/NixOS/nixpkgs/archive/master.tar.gz) {};
in
{
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 =
[
(./. + "/${host}-hardware-configuration.nix")
./avscan-module.nix
./pam_p11
];
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.firewall.allowedTCPPorts = [ 1883 ];
networking.firewall.allowedUDPPorts = [ 1883 ];
time.timeZone = "Asia/Hong_Kong";
@ -50,63 +23,38 @@ in
# $ nix search wget
nixpkgs.config.allowUnfree = true;
environment.systemPackages = with pkgs; [
opensc yubikey-manager yubikey-manager-qt yubico-piv-tool
wget vim gitAndTools.gitFull sshfs
firefox
thunderbird
chromium
usbutils pciutils uhubctl file lm_sensors audacious acpi
opensc yubikey-manager yubikey-manager-qt
wget vim gitAndTools.gitFull firefox chromium thunderbird hexchat
usbutils pciutils file lm_sensors audacious acpi
gimp imagemagick
(python3.withPackages(ps: with ps; [ numpy scipy matplotlib qtconsole regex jinja2 ]))
texlive.combined.scheme-full
(python3.withPackages(ps: with ps; [ numpy scipy matplotlib qtconsole regex ]))
mosh psmisc libreoffice-fresh
inkscape
xournal
xsane
gtkwave unzip zip gnupg
gnome-tweaks
ghex
gtkwave telnet unzip zip gnupg
gnome3.gnome-tweaks
jq sublime3 rink qemu_kvm
tmux screen gdb minicom picocom
artiq.packages.x86_64-linux.openocd-bscanspi
xc3sprog
gqrx
tmux xc3sprog m-labs.openocd screen gdb minicom picocom tigervnc
emacs bat ripgrep
guake
vscodium
waypipe
virt-manager spice-gtk
kicad
any-nix-shell
pkgs-unstable.rust-analyzer
(pkgs-unstable.vscode-with-extensions.override {
vscodeExtensions = [
pkgs-unstable.vscode-extensions.matklad.rust-analyzer
];
})
(import ./fish-nix-shell)
];
programs.wireshark.enable = true;
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.authorizedKeysInHomedir = false;
services.openssh.settings.PasswordAuthentication = false;
services.openssh.extraConfig =
''
StreamLocalBindUnlink yes
'';
programs.mosh.enable = true;
services.openssh.forwardX11 = true;
services.openssh.passwordAuthentication = false;
hardware.u2f.enable = true;
services.pcscd.enable = true;
programs.ssh.extraConfig =
''
PKCS11Provider "${pkgs.opensc}/lib/opensc-pkcs11.so"
'';
programs.ssh.startAgent = true;
services.gnome3.gnome-keyring.enable = pkgs.lib.mkForce false;
programs.ssh.agentPKCS11Whitelist = "${pkgs.opensc}/lib/opensc-pkcs11.so";
security.pam.p11.enable = true;
@ -126,54 +74,76 @@ in
};
services.avahi = {
enable = true;
nssmdns4 = true;
nssmdns = true;
};
hardware.graphics.enable32Bit = true;
# Enable sound.
sound.enable = true;
hardware.pulseaudio = {
enable = true;
extraModules = [ pkgs.pulseaudio-modules-bt ];
package = pkgs.pulseaudioFull;
};
fonts.packages = [ pkgs.noto-fonts pkgs.noto-fonts-cjk-sans pkgs.noto-fonts-emoji pkgs.noto-fonts-extra pkgs.emacs-all-the-icons-fonts ];
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 pkgs.emacs-all-the-icons-fonts ];
# Enable the X11 windowing system.
services.xserver.enable = true;
services.xserver.xkb.layout = "us";
services.xserver.xkb.options = "eurosign:e";
services.xserver.layout = "us";
services.xserver.xkbOptions = "eurosign:e";
# Enable touchpad support.
services.xserver.libinput.enable = true;
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
environment.gnome.excludePackages = [ pkgs.epiphany ];
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"
];
services.xserver.displayManager.gdm.autoSuspend = false;
powerManagement.enable = false;
services.xserver.desktopManager.gnome3.enable = true;
environment.gnome3.excludePackages = [ pkgs.epiphany pkgs.gnome3.geary ];
hardware.bluetooth.enable = true;
programs.zsh.enable = true;
programs.fish.enable = true;
programs.fish.promptInit = ''
any-nix-shell fish --info-right | source
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;
services.udev.packages = [ artiq.packages.x86_64-linux.openocd-bscanspi ];
services.udev.extraRules = (import ./extra-udev.nix);
nix.settings.trusted-public-keys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
nix.settings.substituters = ["https://nixbld.m-labs.hk?priority=10"];
nix.settings.extra-sandbox-paths = ["/opt"];
nix.extraOptions = ''
experimental-features = nix-command flakes impure-derivations
services.udev.packages = [ m-labs.openocd ];
services.udev.extraRules = ''
# leaf maple
SUBSYSTEM=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0003", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0004", MODE="0660", GROUP="plugdev"
# glasgow
SUBSYSTEM=="usb", ATTRS{idVendor}=="20b7", ATTRS{idProduct}=="9db1", MODE="0660", GROUP="plugdev"
# 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?
}

View File

@ -1,27 +0,0 @@
''
# 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"
''

View File

@ -0,0 +1,21 @@
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.

View File

@ -0,0 +1,50 @@
# 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.

View File

@ -0,0 +1,34 @@
#!/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 "$@"

View File

@ -0,0 +1,22 @@
#!/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 "$@"

View File

@ -0,0 +1,21 @@
#!/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

View File

@ -0,0 +1,16 @@
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;
}

View File

@ -1,39 +0,0 @@
# 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";
}

View File

@ -1,3 +1,6 @@
# 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, ... }:
{
@ -18,18 +21,13 @@
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/8C30-F6DC";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices = [ ];
nix.settings.max-jobs = lib.mkDefault 16;
nix.maxJobs = lib.mkDefault 16;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
hardware.cpu.intel.updateMicrocode = true;
system.stateVersion = "19.03";
}

View File

@ -1,3 +1,6 @@
# 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, ... }:
{
@ -18,18 +21,13 @@
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/E085-5F21";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices = [ ];
nix.settings.max-jobs = lib.mkDefault 16;
nix.maxJobs = lib.mkDefault 16;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
hardware.cpu.intel.updateMicrocode = true;
system.stateVersion = "19.03";
}

View File

@ -1,42 +1,30 @@
# 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, ... }:
{ config, lib, pkgs, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [ "ehci_pci" "ata_piix" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/3dca09c8-f725-416a-9f89-b69297698ca9";
{ device = "/dev/disk/by-uuid/62a38d9c-452c-4648-be12-6131e95b8276";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/88F6-46F2";
fsType = "vfat";
};
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.enp5s0.useDHCP = lib.mkDefault true;
nix.maxJobs = lib.mkDefault 8;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
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";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
}

View File

@ -1,43 +0,0 @@
# 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";
}

112
nixops/light.nix Normal file
View File

@ -0,0 +1,112 @@
{ 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;
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?
}

View File

@ -1,23 +1,13 @@
{
network.storage.legacy = {
databasefile = "~/.nixops/deployments.nixops";
};
network.enableRollback = true;
rpi-1 = import ./rpi.nix { host = "rpi-1"; rpi4 = true; };
rpi-1 = import ./rpi.nix { host = "rpi-1"; rpi4 = false; };
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-5 = import ./rpi.nix { host = "rpi-5"; rpi4 = true; };
juno = import ./desktop.nix { host = "juno"; };
zeus = import ./desktop.nix { host = "zeus"; };
hera = import ./desktop.nix { host = "hera"; };
hestia = import ./desktop.nix { host = "hestia"; };
chiron = import ./desktop.nix { host = "chiron"; };
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"; };
cnc = import ./light.nix { host = "cnc"; };
}

View File

@ -1,34 +0,0 @@
# 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";
}

843
nixops/pam_p11/default.nix Normal file
View File

@ -0,0 +1,843 @@
# 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 doesnt 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; };
};
};
}

View File

@ -0,0 +1,23 @@
{ 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 ];
}

View File

@ -1,50 +0,0 @@
# 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";
}

View File

@ -1,22 +1,32 @@
{ host, rpi4, experimental-users ? false }:
{ host, rpi4 }:
{ config, pkgs, ... }:
let
artiq = builtins.getFlake git+https://github.com/m-labs/artiq.git;
m-labs = import (fetchTarball https://nixbld.m-labs.hk/channel/custom/artiq/full/artiq-full/nixexprs.tar.xz) { inherit pkgs; };
in
{
deployment.targetHost = host;
deployment.hasFastConnection = true;
nix.nixPath = [ "nixpkgs=${pkgs.path}" ];
programs.command-not-found.dbPath = "${pkgs.path}/programs.sqlite";
nixpkgs.system = "aarch64-linux";
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;
fileSystems = {
boot.loader.generic-extlinux-compatible.enable = !rpi4;
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";
fsType = "ext4";
@ -24,51 +34,30 @@ in
};
services.openssh.enable = true;
services.openssh.authorizedKeysInHomedir = false;
services.openssh.settings.PasswordAuthentication = false;
services.openssh.settings.GatewayPorts = "clientspecified";
services.openssh.extraConfig =
''
StreamLocalBindUnlink yes
'';
programs.mosh.enable = true;
services.openssh.passwordAuthentication = false;
networking.hostName = host;
time.timeZone = "Asia/Hong_Kong";
users.extraGroups.plugdev = { };
users.mutableUsers = false;
users.defaultUserShell = pkgs.fish;
users.extraUsers = (import ./common-users.nix { inherit pkgs; }) // {
nixbld = {
nix = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGJGICdNM9mHHAa1Cxk9Wz3YLkIEeqrIQGxM0aoy1g5O"
];
};
};
security.sudo.wheelNeedsPassword = false;
services.udev.packages = [ artiq.packages.aarch64-linux.openocd-bscanspi ];
services.udev.extraRules = (import ./extra-udev.nix);
services.udev.packages = [ m-labs.openocd ];
documentation.enable = false;
environment.systemPackages = with pkgs; [
psmisc wget vim git sshfs usbutils uhubctl lm_sensors file mosh tmux
artiq.packages.aarch64-linux.openocd-bscanspi
xc3sprog
screen gdb minicom picocom
psmisc wget vim git usbutils lm_sensors file telnet mosh tmux xc3sprog m-labs.openocd screen gdb minicom picocom
];
programs.zsh.enable = true;
programs.fish.enable = true;
programs.wireshark.enable = true;
nix.settings.trusted-public-keys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
nix.settings.substituters = ["https://nixbld.m-labs.hk?priority=10"];
nix.settings.trusted-users = ["root" "sb"];
nix.extraOptions = ''
experimental-features = nix-command flakes impure-derivations
'';
nix.binaryCachePublicKeys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
nix.binaryCaches = ["https://cache.nixos.org" "https://nixbld.m-labs.hk"];
nix.trustedUsers = ["root" "nix"];
}

View File

@ -1,43 +0,0 @@
# 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";
}

View File

@ -1,41 +0,0 @@
{ 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";
}

View File

@ -1,3 +1,6 @@
# 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, ... }:
{
@ -18,18 +21,13 @@
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/91B4-E546";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices = [ ];
nix.settings.max-jobs = lib.mkDefault 16;
nix.maxJobs = lib.mkDefault 16;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
hardware.cpu.intel.updateMicrocode = true;
system.stateVersion = "19.03";
}

View File

@ -1,49 +0,0 @@
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.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB