Compare commits

..

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

75 changed files with 5637 additions and 7679 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,66 +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";
};
logFile = mkOption {
type = types.str;
default = "/var/lib/afws/logs/afws.log";
description = "Path to the log file";
};
logBackupCount = mkOption {
type = types.int;
default = 30;
description = "Number of daily log files to keep";
};
};
config = mkIf config.services.afws.enable {
systemd.services.afws = {
description = "AFWS server";
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -p "$(dirname ${config.services.afws.logFile})"
chown afws:afws "$(dirname ${config.services.afws.logFile})"
'';
serviceConfig = {
User = "afws";
Group = "afws";
ExecStart = ''
${afws}/bin/afws_server \
--log-file ${config.services.afws.logFile} \
--log-backup-count ${toString config.services.afws.logBackupCount}
'';
ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
};
path = [ pkgs.nix pkgs.git ];
};
security.acme.certs."afws.m-labs.hk".postRun =
''
mkdir -p /var/lib/afws/cert
cp cert.pem /var/lib/afws/cert
cp key.pem /var/lib/afws/cert
chown -R afws:afws /var/lib/afws/cert
'';
security.acme.certs."afws.m-labs.hk".reloadServices = [ "afws.service" ];
users.users.afws = {
name = "afws";
group = "afws";
description = "AFWS server user";
isSystemUser = true;
createHome = false;
home = "/var/lib/afws";
useDefaultShell = true;
};
users.extraGroups.afws = {};
};
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
# Run with: nix-shell flarum-update.nix
{ pkgs ? import <nixpkgs> {}
}:
with pkgs;
let
composer2nix = import (fetchFromGitHub {
owner = "svanderburg";
repo = "composer2nix";
rev = "v0.0.4";
sha256 = "0q0x3in43ss1p0drhc5lp5bnp2jqni1i7zxm7lmjl5aad9nkn3gf";
}) { inherit pkgs; };
in
stdenv.mkDerivation {
name = "flarum-update";
buildInputs = [ phpPackages.composer composer2nix ];
shellHook = ''
OUT=$(pwd)/flarum
cd $(mktemp -d)
composer create-project flarum/flarum . --stability=beta
composer require fof/upload
composer2nix
cp -v *.nix composer.{json,lock} $OUT/
exit
'';
}

View File

@ -0,0 +1,61 @@
{ config, pkgs, ... }:
let
flarumPackage = with pkgs; stdenv.mkDerivation {
name = "flarum-package";
src = fetchFromGitHub {
owner = "flarum";
repo = "flarum";
rev = "v0.1.0-beta.13";
sha256 = "0mj6w7nibdqmi7lx2r5d9yiif6lb584l93551i115a9ly3s4yinn";
};
buildPhase =
''
cp ${./flarum}/* .
'';
installPhase =
''
cp -ar . $out
'';
};
flarum = import "${flarumPackage}" {
inherit pkgs;
noDev = true;
};
cfg = config.services.flarum;
in
{
options.services.flarum = with pkgs.lib; {
user = mkOption {
type = types.str;
default = "nobody";
};
group = mkOption {
type = types.str;
default = "nogroup";
};
installPath = mkOption {
type = types.str;
default = "/var/www/flarum";
};
};
config.systemd.services.flarum-install = {
description = "Flarum installation";
before = [ "nginx.service" "phpfm-flarum.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
};
path = [ pkgs.rsync ];
script = with cfg; ''
mkdir -p ${installPath}
rsync --links --recursive ${flarum}/ ${installPath}
for d in ${installPath} ${installPath}/public/assets \
${installPath}/storage ${installPath}/storage/*
do
chown ${user}:${group} $d
chmod 0775 $d
done
'';
};
}

View File

@ -0,0 +1,238 @@
# This file originates from composer2nix
{ stdenv, writeTextFile, fetchurl, php, unzip, phpPackages }:
let
inherit (phpPackages) composer;
buildZipPackage = { name, src }:
stdenv.mkDerivation {
inherit name src;
buildInputs = [ unzip ];
buildCommand = ''
unzip $src
baseDir=$(find . -type d -mindepth 1 -maxdepth 1)
cd $baseDir
mkdir -p $out
mv * $out
'';
};
buildPackage =
{ name
, src
, packages ? {}
, devPackages ? {}
, buildInputs ? []
, symlinkDependencies ? false
, executable ? false
, removeComposerArtifacts ? false
, postInstall ? ""
, noDev ? false
, unpackPhase ? "true"
, buildPhase ? "true"
, ...}@args:
let
reconstructInstalled = writeTextFile {
name = "reconstructinstalled.php";
executable = true;
text = ''
#! ${php}/bin/php
<?php
if(file_exists($argv[1]))
{
$composerLockStr = file_get_contents($argv[1]);
if($composerLockStr === false)
{
fwrite(STDERR, "Cannot open composer.lock contents\n");
exit(1);
}
else
{
$config = json_decode($composerLockStr, true);
if(array_key_exists("packages", $config))
$allPackages = $config["packages"];
else
$allPackages = array();
${stdenv.lib.optionalString (!noDev) ''
if(array_key_exists("packages-dev", $config))
$allPackages = array_merge($allPackages, $config["packages-dev"]);
''}
$packagesStr = json_encode($allPackages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
print($packagesStr);
}
}
else
print("[]");
?>
'';
};
constructBin = writeTextFile {
name = "constructbin.php";
executable = true;
text = ''
#! ${php}/bin/php
<?php
$composerJSONStr = file_get_contents($argv[1]);
if($composerJSONStr === false)
{
fwrite(STDERR, "Cannot open composer.json contents\n");
exit(1);
}
else
{
$config = json_decode($composerJSONStr, true);
if(array_key_exists("bin-dir", $config))
$binDir = $config["bin-dir"];
else
$binDir = "bin";
if(array_key_exists("bin", $config))
{
if(!file_exists("vendor/".$binDir))
mkdir("vendor/".$binDir);
foreach($config["bin"] as $bin)
symlink("../../".$bin, "vendor/".$binDir."/".basename($bin));
}
}
?>
'';
};
bundleDependencies = dependencies:
stdenv.lib.concatMapStrings (dependencyName:
let
dependency = dependencies.${dependencyName};
in
''
${if dependency.targetDir == "" then ''
vendorDir="$(dirname ${dependencyName})"
mkdir -p "$vendorDir"
${if symlinkDependencies then
''ln -s "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
else
''cp -av "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
}
'' else ''
namespaceDir="${dependencyName}/$(dirname "${dependency.targetDir}")"
mkdir -p "$namespaceDir"
${if symlinkDependencies then
''ln -s "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
else
''cp -av "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
}
''}
'') (builtins.attrNames dependencies);
extraArgs = removeAttrs args [ "name" "packages" "devPackages" "buildInputs" ];
in
stdenv.mkDerivation ({
name = "composer-${name}";
buildInputs = [ php composer ] ++ buildInputs;
inherit unpackPhase buildPhase;
installPhase = ''
${if executable then ''
mkdir -p $out/share/php
cp -av $src $out/share/php/$name
chmod -R u+w $out/share/php/$name
cd $out/share/php/$name
'' else ''
cp -av $src $out
chmod -R u+w $out
cd $out
''}
# Remove unwanted files
rm -f *.nix
export HOME=$TMPDIR
# Remove the provided vendor folder if it exists
rm -Rf vendor
# If there is no composer.lock file, compose a dummy file.
# Otherwise, composer attempts to download the package.json file from
# the registry which we do not want.
if [ ! -f composer.lock ]
then
cat > composer.lock <<EOF
{
"packages": []
}
EOF
fi
# Reconstruct the installed.json file from the lock file
mkdir -p vendor/composer
${reconstructInstalled} composer.lock > vendor/composer/installed.json
# Copy or symlink the provided dependencies
cd vendor
${bundleDependencies packages}
${stdenv.lib.optionalString (!noDev) (bundleDependencies devPackages)}
cd ..
# Reconstruct autoload scripts
# We use the optimize feature because Nix packages cannot change after they have been built
# Using the dynamic loader for a Nix package is useless since there is nothing to dynamically reload.
composer dump-autoload --optimize ${stdenv.lib.optionalString noDev "--no-dev"}
# Run the install step as a validation to confirm that everything works out as expected
composer install --optimize-autoloader ${stdenv.lib.optionalString noDev "--no-dev"}
${stdenv.lib.optionalString executable ''
# Reconstruct the bin/ folder if we deploy an executable project
${constructBin} composer.json
ln -s $(pwd)/vendor/bin $out/bin
''}
${stdenv.lib.optionalString (!symlinkDependencies) ''
# Patch the shebangs if possible
if [ -d $(pwd)/vendor/bin ]
then
# Look for all executables in bin/
for i in $(pwd)/vendor/bin/*
do
# Look for their location
realFile=$(readlink -f "$i")
# Restore write permissions
chmod u+wx "$(dirname "$realFile")"
chmod u+w "$realFile"
# Patch shebang
sed -e "s|#!/usr/bin/php|#!${php}/bin/php|" \
-e "s|#!/usr/bin/env php|#!${php}/bin/php|" \
"$realFile" > tmp
mv tmp "$realFile"
chmod u+x "$realFile"
done
fi
''}
if [ "$removeComposerArtifacts" = "1" ]
then
# Remove composer stuff
rm -f composer.json composer.lock
fi
# Execute post install hook
runHook postInstall
'';
} // extraArgs);
in
{
composer = stdenv.lib.makeOverridable composer;
buildZipPackage = stdenv.lib.makeOverridable buildZipPackage;
buildPackage = stdenv.lib.makeOverridable buildPackage;
}

View File

@ -0,0 +1,69 @@
{
"name": "flarum/flarum",
"description": "Delightfully simple forum software.",
"type": "project",
"keywords": [
"forum",
"discussion"
],
"homepage": "https://flarum.org/",
"license": "MIT",
"authors": [
{
"name": "Franz Liedke",
"email": "franz@develophp.org"
},
{
"name": "Daniel Klabbers",
"email": "daniel@klabbers.email",
"homepage": "https://luceos.com"
},
{
"name": "David Sevilla Martin",
"email": "me+flarum@datitisev.me",
"homepage": "https://datitisev.me"
},
{
"name": "Clark Winkelmann",
"email": "clark.winkelmann@gmail.com",
"homepage": "https://clarkwinkelmann.com"
},
{
"name": "Matthew Kilgore",
"email": "matthew@kilgore.dev"
}
],
"support": {
"issues": "https://github.com/flarum/core/issues",
"source": "https://github.com/flarum/flarum",
"docs": "https://flarum.org/docs/"
},
"require": {
"flarum/approval": "^0.1.0",
"flarum/auth-facebook": "^0.1.0",
"flarum/auth-github": "^0.1.0",
"flarum/auth-twitter": "^0.1.0",
"flarum/bbcode": "^0.1.0",
"flarum/core": "^0.1.0",
"flarum/emoji": "^0.1.0",
"flarum/flags": "^0.1.0",
"flarum/lang-english": "^0.1.0",
"flarum/likes": "^0.1.0",
"flarum/lock": "^0.1.0",
"flarum/markdown": "^0.1.0",
"flarum/mentions": "^0.1.0",
"flarum/pusher": "^0.1.0",
"flarum/statistics": "^0.1.0",
"flarum/sticky": "^0.1.0",
"flarum/subscriptions": "^0.1.0",
"flarum/suspend": "^0.1.0",
"flarum/tags": "^0.1.0",
"fof/upload": "^0.10.0"
},
"config": {
"preferred-install": "dist",
"sort-packages": true
},
"minimum-stability": "beta",
"prefer-stable": true
}

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,13 @@
{ {pkgs ? import <nixpkgs> {
lib, inherit system;
php, }, system ? builtins.currentSystem, noDev ? false}:
fetchFromGitHub,
fetchpatch,
}:
php.buildComposerProject (finalAttrs: { let
pname = "flarum"; composerEnv = import ./composer-env.nix {
version = "1.8.1"; inherit (pkgs) stdenv writeTextFile fetchurl php unzip phpPackages;
src = fetchFromGitHub {
owner = "flarum";
repo = "flarum";
rev = "v${finalAttrs.version}";
hash = "sha256-kigUZpiHTM24XSz33VQYdeulG1YI5s/M02V7xue72VM=";
}; };
in
patches = [ import ./php-packages.nix {
# Add useful extensions from https://github.com/FriendsOfFlarum inherit composerEnv noDev;
# Extensions included: fof/upload, fof/polls, fof/subscribed inherit (pkgs) fetchurl fetchgit fetchhg fetchsvn;
./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",

File diff suppressed because it is too large Load Diff

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

@ -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

@ -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

@ -0,0 +1,84 @@
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 53a0958a..16a98aec 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -809,9 +809,16 @@ private:
/* Whether this is a fixed-output derivation. */
bool fixedOutput;
+ bool networked;
+
/* Whether to run the build in a private network namespace. */
bool privateNetwork = false;
+ bool allowNetwork()
+ {
+ return fixedOutput || networked;
+ }
+
typedef void (DerivationGoal::*GoalState)();
GoalState state;
@@ -1179,6 +1186,8 @@ void DerivationGoal::haveDerivation()
{
trace("have derivation");
+ fixedOutput = drv->isFixedOutput();
+
retrySubstitution = false;
for (auto & i : drv->outputs)
@@ -1195,6 +1204,8 @@ void DerivationGoal::haveDerivation()
parsedDrv = std::make_unique<ParsedDerivation>(drvPath, *drv);
+ networked = parsedDrv->getBoolAttr("__networked");
+
/* We are first going to try to create the invalid output paths
through substitutes. If that doesn't work, we'll build
them. */
@@ -1987,7 +1998,7 @@ void DerivationGoal::startBuilder()
else if (settings.sandboxMode == smDisabled)
useChroot = false;
else if (settings.sandboxMode == smRelaxed)
- useChroot = !fixedOutput && !noChroot;
+ useChroot = !allowNetwork() && !noChroot;
}
if (worker.store.storeDir != worker.store.realStoreDir) {
@@ -2153,7 +2164,7 @@ void DerivationGoal::startBuilder()
"nogroup:x:65534:\n") % sandboxGid).str());
/* Create /etc/hosts with localhost entry. */
- if (!fixedOutput)
+ if (!allowNetwork())
writeFile(chrootRootDir + "/etc/hosts", "127.0.0.1 localhost\n::1 localhost\n");
/* Make the closure of the inputs available in the chroot,
@@ -2361,7 +2372,7 @@ void DerivationGoal::startBuilder()
us.
*/
- if (!fixedOutput)
+ if (!allowNetwork())
privateNetwork = true;
userNamespaceSync.create();
@@ -2573,7 +2584,7 @@ void DerivationGoal::initEnv()
to the builder is generally impure, but the output of
fixed-output derivations is by definition pure (since we
already know the cryptographic hash of the output). */
- if (fixedOutput) {
+ if (allowNetwork()) {
for (auto & i : parsedDrv->getStringsAttr("impureEnvVars").value_or(Strings()))
env[i] = getEnv(i).value_or("");
}
@@ -3184,7 +3195,7 @@ void DerivationGoal::runChild()
/* Fixed-output derivations typically need to access the
network, so give them access to /etc/resolv.conf and so
on. */
- if (fixedOutput) {
+ if (allowNetwork()) {
ss.push_back("/etc/resolv.conf");
// Only use nss functions to resolve hosts and

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() load_dotenv()
mail_password_file = getenv("FLASK_MAIL_PASSWORD_FILE")
if mail_password_file is not None:
with open(mail_password_file, "r") as f:
mail_password = f.read().strip()
else:
mail_password = None
app = Flask(__name__) app = Flask(__name__)
app.config.update( app.config.update(
DEBUG=getenv("FLASK_DEBUG") == "True", DEBUG=getenv("FLASK_DEBUG") == "True",
@ -29,7 +22,7 @@ app.config.update(
MAIL_USE_SSL=getenv("FLASK_MAIL_USE_SSL"), MAIL_USE_SSL=getenv("FLASK_MAIL_USE_SSL"),
MAIL_DEBUG=False, MAIL_DEBUG=False,
MAIL_USERNAME=getenv("FLASK_MAIL_USERNAME"), MAIL_USERNAME=getenv("FLASK_MAIL_USERNAME"),
MAIL_PASSWORD=mail_password, MAIL_PASSWORD=getenv("FLASK_MAIL_PASSWORD"),
MAIL_RECIPIENT=getenv("FLASK_MAIL_RECIPIENT"), MAIL_RECIPIENT=getenv("FLASK_MAIL_RECIPIENT"),
MAIL_SENDER=getenv("FLASK_MAIL_SENDER") MAIL_SENDER=getenv("FLASK_MAIL_SENDER")
) )

View File

@ -7,13 +7,13 @@ in {
pythonPackages = self: [ pkg ]; pythonPackages = self: [ pkg ];
module = "rfq:app"; module = "rfq:app";
env = [ env = [
"FLASK_MAIL_SERVER=mail.m-labs.hk" "FLASK_MAIL_SERVER=ssl.serverraum.org"
"FLASK_MAIL_PORT=465" "FLASK_MAIL_PORT=465"
"FLASK_MAIL_USE_SSL=True" "FLASK_MAIL_USE_SSL=True"
"FLASK_MAIL_USERNAME=sysop@m-labs.hk" "FLASK_MAIL_USERNAME=sales@m-labs.hk"
"FLASK_MAIL_PASSWORD_FILE=/etc/nixos/secret/rfqpassword" "FLASK_MAIL_PASSWORD=${import /etc/nixos/secret/sales_password.nix}"
"FLASK_MAIL_RECIPIENT=sales@m-labs.hk" "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"; socket = "${config.services.uwsgi.runDir}/uwsgi-rfq.sock";
# allow access from nginx # 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 backup-passphrase
-rw------- 1 root root email_accounts.nix -rw------- 1 root root email_accounts.nix
-rw------- 1 root root gitea_tokens.nix -rw------- 1 homu homu homu.toml
-rw------- 1 root root github_tokens.nix
-rw-rw---- 1 gitea gitea mailerpassword -rw-rw---- 1 gitea gitea mailerpassword
-rw------- 1 matterbridge matterbridge matterbridge.toml -rw------- 1 matterbridge matterbridge matterbridge.toml
-rw------- 1 uwsgi uwsgi mattermost-github-integration.py -rw------- 1 uwsgi uwsgi mattermost-github-integration.py
-rw------- 1 nginx nginx muninpasswd -rw------- 1 nginx nginx muninpasswd
-rw-rw---- 1 hydra hydra nixbld.m-labs.hk-1 -rw-rw---- 1 hydra hydra nixbld.m-labs.hk-1
-rw-rw---- 1 hydra hydra nix_id_rsa
-rw------- 1 root root rclone.conf
-rw------- 1 root root wifi_password.nix -rw------- 1 root root wifi_password.nix
-rw------- 1 sb users wifi_ext_password.nix

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

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, ... }: { pkgs, ... }:
{ {
root = {
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF/YybP+fQ0J+bNqM5Vgx5vDmVqVWsgUdF1moUxghv7d73GZAFaM6IFBdrXTAa33AwnWwDPMrTgP1V6SXBkb3ciJo/lD1urJGbydbSI5Ksq9d59wvOeANvyWYrQw6+eqTQ=="
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMALVC8RDTHec+PC8y1s3tcpUAODgq6DEzQdHDf/cyvDMfmCaPiMxfIdmkns5lMa03hymIfSmLUF0jFFDc7biRp7uf9AAXNsrTmplHii0l0McuOOZGlSdZM4eL817P7UwJqFMxJyFXDjkubhQiX6kp25Kfuj/zLnupRCaiDvE7ho/xay6Jrv0XLz935TPDwkc7W1asLIvsZLheB+sRz9SMOb9gtrvk5WXZl5JTOFOLu+JaRwQLHL/xdcHJTOod7tqHYfpoC5JHrEwKzbhTOwxZBQBfTQjQktKENQtBxXHTe71rUEWfEZQGg60/BC4BrRmh4qJjlJu3v4VIhC7SSHn1"
];
};
sb = { sb = {
isNormalUser = true; isNormalUser = true;
extraGroups = ["wheel" "plugdev" "dialout" "libvirtd"]; extraGroups = ["wheel" "plugdev" "dialout"];
openssh.authorizedKeys.keys = [ 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" "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMALVC8RDTHec+PC8y1s3tcpUAODgq6DEzQdHDf/cyvDMfmCaPiMxfIdmkns5lMa03hymIfSmLUF0jFFDc7biRp7uf9AAXNsrTmplHii0l0McuOOZGlSdZM4eL817P7UwJqFMxJyFXDjkubhQiX6kp25Kfuj/zLnupRCaiDvE7ho/xay6Jrv0XLz935TPDwkc7W1asLIvsZLheB+sRz9SMOb9gtrvk5WXZl5JTOFOLu+JaRwQLHL/xdcHJTOod7tqHYfpoC5JHrEwKzbhTOwxZBQBfTQjQktKENQtBxXHTe71rUEWfEZQGg60/BC4BrRmh4qJjlJu3v4VIhC7SSHn1"
]; ];
}; };
@ -25,98 +19,65 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMUaB2G1jexxfkdlly3fdWslH54/s/bOuvk9AxqpjtAY robert-jordens-ed25519" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMUaB2G1jexxfkdlly3fdWslH54/s/bOuvk9AxqpjtAY robert-jordens-ed25519"
]; ];
}; };
harry = {
guest = { isNormalUser = true;
extraGroups = ["plugdev" "dialout" "wireshark"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDcPNCgtdz8erFPRrAwCr4JrkeYXJUUvoRBgP0X2HlzJgDe1Inuo6sC6CGcO3IXbf4MwVA9XEp8BYPHARVeEHhufg/0wnIABLx2GcK99yxOLDUe4h/3YwtqvOcqHEsDx7w=="
];
};
astro = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout" "wireshark"];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGJJTSJdpDh82486uPiMhhyhnci4tScp5uUe7156MBC8 a"
];
shell = pkgs.bashInteractive;
};
pca006132 = {
isNormalUser = true; isNormalUser = true;
extraGroups = ["plugdev" "dialout"]; extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPsv4UMEFV0UHeHdA9R3sC+qoMxrqhcuFqwqWMI4AF/lixwcbRyA8QKiu/7R22m2u6pp+Zk6hYqcxdgClI4uN2oQhVjJX6wEgfT94vC/67OKJI/NNVsR8G0lr0ufCo4Lbw==" "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE/sPOOiw3843+rrcYV2pOVkffNc1xsOgnuCUmy1Fa2VF8x9kqmgQv61sxsuKRkKKoinvqrASxLkWVd6nkiiDuEISibEXs8r1BwuT05cS7RkEhCakSMZ6y/iqOtjt2bx+A=="
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCrC43AF/aHv9NHormDMw18m/iE3luNc4CIwgPgTClly4b9yRyQGhm4mKkKix07fP9SfdyvUPPrYhwoHhf0zGkfFNE26FIG2Bul9UkZVP3ygnIXHD7sKUJP7Ra4UID6Naf3Mr2Dckh7rAiw8WN2QB+oO2tni3PyceEOdu8OoEsmSu8qusJFVhnaoYJyQflgGl3bFUZkhaf1JKQmv9C92sfKQkrfSNb2dNrc3Oe1uP5VokhLhjsOoDWyJ45a7ru6lr4/Co5sF9xX59cOOBU+ktiOakDI8NLI5AO7R0dCKLW55wUnml5boeCV45p1MPXVEznX8IM6kRgOhVx3fnd0TqV5M8xeY0dk7aTWTFSkIz82xHhKFbce5xx+9MFrlvUgHYVpbIUQTq6HS6cLZEeWHDLuUqbRFB4J7UfieiRZfxWw74Tgyq+HlvlNg/cVn0nhouq6+sY6QI9MGbwbEnjkD5KbSUHUCSeLgNc8pb0RxLkAqPGh8QkYrb6Nudl8HjWfIuZFGrRhcGBySt/oaYUDrUg5VNA98FjQL2QfKRVepvpGgUEGW6eZK9IrYz1Ct30Sb65QujUMRuDnWq1CeulAXCZQHc32wOrHRkMEUdhfOgNojZRTGduPayHXoDq7XB249D2VjH/vEuiLfWNLr+rabGyMUPpQaDypeBgOsUTbceKbDw=="
]; ];
shell = pkgs.zsh;
}; };
occheung = { occheung = {
isNormalUser = true; isNormalUser = true;
extraGroups = ["plugdev" "dialout"]; extraGroups = ["plugdev" "dialout" "wireshark"];
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPEvmWmxpFpMgp5fpjKud8ev0cyf/+X5fEpQt/YD/+u4mbvZYPE300DLqQ0h/qjgvaGMz1ndf4idYnRdy+plJEC/+hmlRW5NlcpAr3S/LYAisacgKToFVl+MlBo+emS9Ig==" "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPEvmWmxpFpMgp5fpjKud8ev0cyf/+X5fEpQt/YD/+u4mbvZYPE300DLqQ0h/qjgvaGMz1ndf4idYnRdy+plJEC/+hmlRW5NlcpAr3S/LYAisacgKToFVl+MlBo+emS9Ig=="
]; ];
}; };
spaqin = { dsleung = {
isNormalUser = true; isNormalUser = true;
extraGroups = ["plugdev" "dialout"]; extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOtmlQmIK/cEUkcwA/y9jC4AohjoEmikerpxzPhZZtOcENidN/vFum58jIcSxBvjHnILOzhfCTeLvbvGbQOFE53a7FOyEHmIzXRKS86Mg5bPHUBJxRSq9MjulGZXES3HOQ==" "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDbE7HzZKSwGbgRnzwrzCzb3gZKLSritwnEpHS4sa9oXJ5oLFkuFZOpPYDeiMlbUJ9jCk5FRmkLYIkrbz06SUr7P/eUjxu79ENi3RhfVu+ZrrPvgkhKvM/CiXvw3xCOu0w=="
];
shell = pkgs.zsh;
};
srayman89 = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout" "libvirtd"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBMoGOV9HoFkm6S6zMfOc8ivUcGzKFxuqpmOXKQtg2nn5Kh6ByMuuAHFlvKISILBaWgXN8lPQN9VjLuXV93oG4Pe7u8EVw20IGbA6RZ4Pnnr1xQBESPbye+72taLvyQlxGA=="
]; ];
}; };
esavkin = { cw = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout" "libvirtd" "wireshark"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBLDJI4GFLBmScbeR8Jh4Gi8A/2nuGlYtFTJVT+Es/bzdiPRk8DLG62T0hyRR+8LfHjbrCsDuYFNztT8hHGXd7h3xp3y2X7ArkJo8xUK5QxGd5D2Zn4ANfZTTVkoGlEHbFA=="
];
};
flo = {
isNormalUser = true; isNormalUser = true;
extraGroups = ["plugdev" "dialout"]; extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF4ZYNBYqJPQCKBYjMatFj5eGMyzh/X2TSraJEG6XBdg3jnJ3WcsOd7sm+vx+o9Y1EJ2kvwW/Vy9c3OYVU2U45njox//sKtt8Eyzszws3EYJqHQ6KAwXtW9ao4aamRtK3Q==" "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBKsbGwnWUZpH7uyli0RR1oOCZJaVGNg/ZeIP3BIjowr2I9YSDqlbgXG3grgLAxiNL7a/RRh9naR+5ViWpoZGSt90RouUK3S6u7JR7oso7tcI50/9xro8g3ZDwCncGxkXDA=="
]; ];
}; };
srenblad = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBLoMzO8XIkUTKUC0R05EmXn3V6gm2oMvXhh+j68G9TDBeb8x0WFkz16NPclsXdMcb2dFhtLmxUHwB5L4zWSuyYkqr0YRrtly3uwXe5Wnyz1ZAkxoq7YjQlanWSri11U8xw=="
];
};
linuswck = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout" "wireshark" "libvirtd"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBAFYwmik6/xY1vb9aKBOpKklKOwSJJ0PEgNwWNULghZGJ0g4CTk04LXLSMYBm1SW74df8YMgaE/eoidq6smN6hKIgo8s3qPQGZAi4UXffMs2ciqXNa/zZcCu3PyZvyksxA=="
];
};
morgan = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout" "wireshark" "libvirtd"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDXMbJEPn0mM2Bgt6eMAd+c0J5oPSvquZG+BxKdUf0qbeQldRaoB26NHMZnLte/fS00U/cqStLWDiwtEvH5WlbbawsMBymm65zbWMByebXhBDjdr6a1kkOFcKJvAL9qVBQ=="
];
};
atse = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJHMX1YDnBPQfZyGVtc93u4TIFWqnHEe6WB/eTeiOjFulitXzGfhsODZ08GzTi2+YKk7spRiPKNwRPTKFuW2PPe3Xig8b75qRMIeIVX3b7e0i6xP85eg4jdiz0LD2YGUHQ=="
];
};
derppening = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOKwN4ui94QfouYYlkI1lc3WgtjURVYLTdAizJIBnY3dNRNblAiuvTD4pQ+LEI+eOTg4SnQz1NeqH4YOQhbT5+/nZojvGTb3UVN13ZYND+Gci3DdqB2mwIYop7kMXwHgLQ=="
];
};
therobs12 = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBK1tUg7TtceARRnGI80Ai5kNFolFfZ++LH9v1UoRCiJdxeQWPdNYO0Gj7+ejJvgZXwvN4yHGgcZHraEml4Mj/dKrEMFygfuYLDRmXtPFwX6TNMrWlxMhPzuNY+yCaxlqYg=="
];
};
dpn = { dpn = {
isNormalUser = true; isNormalUser = true;
extraGroups = ["plugdev" "dialout"]; extraGroups = ["plugdev" "dialout" "wireshark"];
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDB/3vRS5HKRz8RHTqrlb5P54A2UJnrffhnuqoHwy5OLr+h5j6MA9yu8LYCBx87LI4M4AKc6eJo//e793mqYXGq8Gp4MMzxglgKEnrw0a41CerXZNt5M4c9Jy5io1L73etoY0RwuexH27RIGrJ0nNazlLEmOr5J4Z/sqikDBKi8f8Z0BS5/SlkhSRCtl6T3uDM7W3Wl04ZJF/vP0tEuvU9lYk99ujt9Ll/D2TXfJTezBtugADas5Te+D5I1RDF9Bc2L7zp6nP/TEzvXwA8+rfAf+Prd4MpPGt0OtLxWgjo21lx7gKM9WoZMBL6qjn3iemveEVu48yoi1MpHyTmT/qwTYWk4hVz7LdqVUYPszAVxFr89A4qfmE4AWSEOqALeaOM9jUJK4ZO33fT94HpgtjKJut+vdQfjRl2caxOJu34BBFn2cYMOZaDIUCuNOmYGhj3nzI/wzXB7EH4J+KCEyAEGRYakADqttBRCD3Znw6mzlOjfu4bMlylrPb9/Ajsafwk="
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGChLocYJi8XcSJkIjT2Olm3jPGjtRq5aORa5G9F3OqmjCfvav9Q5+2Mc64XqHtNTffnJuDe4gv+lVJatC0URvPs2HyxXmxRK0jgkkLSUsV2SYLlgMqHW3jsrdh6wKBmkg==" "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGChLocYJi8XcSJkIjT2Olm3jPGjtRq5aORa5G9F3OqmjCfvav9Q5+2Mc64XqHtNTffnJuDe4gv+lVJatC0URvPs2HyxXmxRK0jgkkLSUsV2SYLlgMqHW3jsrdh6wKBmkg=="
]; ];
}; };
tom = {
isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDMviQek/1Wj525Y5QQb3fXimJ9srOgWJNBxKKB5xfOzEzlU/MQr49sUSyq1+wUXOc2lHjQQb4aNbs8QyzhgynvlZZ4C/scFXLv83V8SFd8fXb8YiJ5OXBCxiHAZWJF/99kxQNeLvp3qvU+hWG3nLHd6NDTbyqG+EIEaZkJsVbdCzL/ERUbCZPNkfgY5zv62i9zR8XJtt77lyCprOs4q27wD+FplkjN3skeWJYr0F+yuf2DEC1ZrOS1uYHVgPlOZRSQq8qtWr4K4ZMrFJ0Ul7Qzj/GjtqH59QZFcVgoHJhlSM5MUNn863IKuLPmHOsTYqA57bPj+vulMZwt63Qw0ehpVZnUo3MZjfI/fS5Ox8c0B+7/JmGXxQVe+mQ6feg24h3C3+npzI6VbGXr09+ka36d7bRDJdY6/LEhQZTiwXrwOxstFjbEucGDPFx0rsqDxPeQ77mA0GQw2J/hYr6kc+KDIipclxqq6tE6LEYaAzeiTePU+QSutLsOzEpXezY3vINd/Tp8oySQBliseKsByPV8m37egTHheLNbVvh6a4sfhm68MGDYNBAKGHyMpnnDf/G1PVf97wq0YpQWoCrYNbp7QQZST0UjEk8hARnI/UuZtkYOaube0lcO0zaMUtmX8Qq4dq+RMblcwjWVsqExljFNEhjJqRRY7ZfpJ5OdeiXFLQ=="
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJ+FieYdkTS3BomeEVp7SMGD3HYDzdQHKi1WgqiFF5c3CYjFiwc/W/NrsCavEkLM9GrLKS1OKxHlG6gpsMGxiHuidoK7NDd3NhHL2jJFzH7haFktJ5DrkfRPPi4QPscZPg=="
];
};
} }

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, ... }: { config, pkgs, ... }:
let 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 in
{ {
deployment.targetHost = host; deployment.targetHost = host;
deployment.hasFastConnection = true;
nix.nixPath = [ "nixpkgs=${pkgs.path}" ];
programs.command-not-found.dbPath = "${pkgs.path}/programs.sqlite";
boot.loader.systemd-boot.memtest86.enable = true;
boot.loader.grub.memtest86.enable = true;
disabledModules = [ "security/pam.nix" ];
imports = imports =
[ [
(./. + "/${host}-hardware-configuration.nix") (./. + "/${host}-hardware-configuration.nix")
./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.hostName = host;
networking.firewall.allowedTCPPorts = [ 1883 ];
networking.firewall.allowedUDPPorts = [ 1883 ];
time.timeZone = "Asia/Hong_Kong"; time.timeZone = "Asia/Hong_Kong";
@ -50,63 +23,46 @@ in
# $ nix search wget # $ nix search wget
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
opensc yubikey-manager yubikey-manager-qt yubico-piv-tool opensc yubikey-manager yubikey-manager-qt
wget vim gitAndTools.gitFull sshfs wget vim gitAndTools.gitFull firefox chromium thunderbird hexchat
firefox usbutils pciutils file lm_sensors audacious acpi
thunderbird
chromium
usbutils pciutils uhubctl file lm_sensors audacious acpi
gimp imagemagick gimp imagemagick
(python3.withPackages(ps: with ps; [ numpy scipy matplotlib qtconsole regex jinja2 ])) (python3.withPackages(ps: with ps; [ numpy scipy matplotlib qtconsole regex ]))
texlive.combined.scheme-full
mosh psmisc libreoffice-fresh mosh psmisc libreoffice-fresh
inkscape gtkwave telnet unzip zip gnupg
xournal gnome3.gnome-tweaks
xsane
gtkwave unzip zip gnupg
gnome-tweaks
ghex
jq sublime3 rink qemu_kvm jq sublime3 rink qemu_kvm
tmux screen gdb minicom picocom tmux xc3sprog m-labs.openocd screen gdb minicom picocom tigervnc
artiq.packages.x86_64-linux.openocd-bscanspi
xc3sprog
gqrx
emacs bat ripgrep emacs bat ripgrep
guake pkgs-unstable.xpra
vscodium pkgs-unstable.rust-analyzer
waypipe (pkgs-unstable.vscode-with-extensions.override {
virt-manager spice-gtk vscodeExtensions = [
kicad pkgs-unstable.vscode-extensions.matklad.rust-analyzer
any-nix-shell ];
})
(import ./fish-nix-shell)
]; ];
programs.wireshark.enable = true; programs.wireshark.enable = true;
programs.wireshark.package = pkgs.wireshark; programs.wireshark.package = pkgs.wireshark;
virtualisation.libvirtd.enable = true;
virtualisation.libvirtd.qemu.ovmf.enable = true;
security.wrappers.spice-client-glib-usb-acl-helper = {
source = "${pkgs.spice-gtk}/bin/spice-client-glib-usb-acl-helper";
owner = "root";
group = "root";
setuid = true;
};
services.avscan.enable = true;
services.openssh.enable = true; services.openssh.enable = true;
services.openssh.authorizedKeysInHomedir = false; services.openssh.forwardX11 = true;
services.openssh.settings.PasswordAuthentication = false; services.openssh.passwordAuthentication = false;
services.openssh.extraConfig = services.openssh.extraConfig =
'' ''
StreamLocalBindUnlink yes StreamLocalBindUnlink yes
''; '';
programs.mosh.enable = true; programs.mosh.enable = true;
hardware.u2f.enable = true;
services.pcscd.enable = true; services.pcscd.enable = true;
programs.ssh.extraConfig = programs.ssh.extraConfig =
'' ''
PKCS11Provider "${pkgs.opensc}/lib/opensc-pkcs11.so" PKCS11Provider "${pkgs.opensc}/lib/opensc-pkcs11.so"
''; '';
programs.ssh.startAgent = true; programs.ssh.startAgent = true;
services.gnome3.gnome-keyring.enable = pkgs.lib.mkForce false;
programs.ssh.agentPKCS11Whitelist = "${pkgs.opensc}/lib/opensc-pkcs11.so"; programs.ssh.agentPKCS11Whitelist = "${pkgs.opensc}/lib/opensc-pkcs11.so";
security.pam.p11.enable = true; security.pam.p11.enable = true;
@ -126,54 +82,78 @@ in
}; };
services.avahi = { services.avahi = {
enable = true; 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. # Enable the X11 windowing system.
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.xkb.layout = "us"; services.xserver.layout = "us";
services.xserver.xkb.options = "eurosign:e"; services.xserver.xkbOptions = "eurosign:e";
# Enable touchpad support.
services.xserver.libinput.enable = true;
services.xserver.displayManager.gdm.enable = true; services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true; services.xserver.displayManager.gdm.autoSuspend = false;
environment.gnome.excludePackages = [ pkgs.epiphany ]; powerManagement.enable = false;
services.xserver.desktopManager.gnome3.enable = true;
systemd.suppressedSystemUnits = [ environment.gnome3.excludePackages = [ pkgs.epiphany pkgs.gnome3.geary ];
"hibernate.target"
"suspend.target"
"suspend-then-hibernate.target"
"sleep.target"
"hybrid-sleep.target"
"systemd-hibernate.service"
"systemd-hybrid-sleep.service"
"systemd-suspend.service"
"systemd-suspend-then-hibernate.service"
];
hardware.bluetooth.enable = true; hardware.bluetooth.enable = true;
programs.zsh.enable = true;
programs.fish.enable = true; programs.fish.enable = true;
programs.fish.promptInit = '' programs.fish.promptInit = ''
any-nix-shell fish --info-right | source fish-nix-shell --info-right | source
''; '';
users.mutableUsers = false; users.mutableUsers = false;
users.defaultUserShell = pkgs.fish; users.defaultUserShell = pkgs.fish;
users.extraGroups.plugdev = { }; users.extraGroups.plugdev = { };
users.extraUsers = import ./common-users.nix { inherit pkgs; }; users.extraUsers = import ./common-users.nix { inherit pkgs; };
security.sudo.wheelNeedsPassword = false; security.sudo.wheelNeedsPassword = false;
services.udev.packages = [ artiq.packages.x86_64-linux.openocd-bscanspi ]; services.udev.packages = [ m-labs.openocd ];
services.udev.extraRules = (import ./extra-udev.nix); services.udev.extraRules = ''
# leaf maple
nix.settings.trusted-public-keys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="]; SUBSYSTEM=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0003", MODE="0660", GROUP="plugdev"
nix.settings.substituters = ["https://nixbld.m-labs.hk?priority=10"]; SUBSYSTEM=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0004", MODE="0660", GROUP="plugdev"
nix.settings.extra-sandbox-paths = ["/opt"]; # STM32 devkit
SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374e", MODE="0660", GROUP="plugdev"
nix.extraOptions = '' # glasgow
experimental-features = nix-command flakes impure-derivations 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, ... }: { config, lib, pkgs, ... }:
{ {
@ -18,18 +21,13 @@
fileSystems."/boot" = fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/8C30-F6DC"; { device = "/dev/disk/by-uuid/8C30-F6DC";
fsType = "vfat"; fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
}; };
swapDevices = [ ]; swapDevices = [ ];
nix.settings.max-jobs = lib.mkDefault 16; nix.maxJobs = lib.mkDefault 16;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
hardware.cpu.intel.updateMicrocode = true;
system.stateVersion = "19.03";
} }

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

View File

@ -1,42 +1,30 @@
# Do not modify this file! It was generated by nixos-generate-config { config, lib, pkgs, ... }:
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
imports = 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.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ]; boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
fileSystems."/" = fileSystems."/" =
{ device = "/dev/disk/by-uuid/3dca09c8-f725-416a-9f89-b69297698ca9"; { device = "/dev/disk/by-uuid/62a38d9c-452c-4648-be12-6131e95b8276";
fsType = "ext4"; fsType = "ext4";
}; };
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/88F6-46F2";
fsType = "vfat";
};
swapDevices = [ ]; swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking nix.maxJobs = lib.mkDefault 8;
# (the default) this is the recommended approach. When using systemd-networkd it's powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
# 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;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; boot.loader.systemd-boot.enable = true;
hardware.cpu.intel.updateMicrocode = true; boot.loader.efi.canTouchEfiVariables = 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";
} }

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";
}

118
nixops/light.nix Normal file
View File

@ -0,0 +1,118 @@
{ host }:
{ config, pkgs, ... }:
{
deployment.targetHost = host;
disabledModules = [ "security/pam.nix" ];
imports =
[
(./. + "/${host}-hardware-configuration.nix")
./pam_p11
];
networking.hostName = host;
time.timeZone = "Asia/Hong_Kong";
# List packages installed in system profile. To search, run:
# $ nix search wget
documentation.enable = false;
nixpkgs.config.allowUnfree = true;
environment.systemPackages = with pkgs; [
opensc
wget vim git firefox usbutils pciutils file lm_sensors acpi
gimp imagemagick
(python3.withPackages(ps: with ps; [ numpy scipy ]))
psmisc
telnet unzip zip gnupg
sublime3 rink
tmux screen tigervnc
(import ./fish-nix-shell)
];
programs.wireshark.enable = true;
services.openssh.enable = true;
services.openssh.forwardX11 = true;
services.openssh.passwordAuthentication = false;
services.openssh.extraConfig =
''
StreamLocalBindUnlink yes
'';
programs.mosh.enable = true;
hardware.u2f.enable = true;
services.pcscd.enable = true;
programs.ssh.extraConfig =
''
PKCS11Provider "${pkgs.opensc}/lib/opensc-pkcs11.so"
'';
programs.ssh.startAgent = true;
programs.ssh.agentPKCS11Whitelist = "${pkgs.opensc}/lib/opensc-pkcs11.so";
security.pam.p11.enable = true;
# Enable CUPS to print documents.
services.printing = {
enable = true;
extraConf =
''
Browsing Off
BrowseLocalProtocols none
'';
browsedConf =
''
BrowseRemoteProtocols none
BrowseProtocols none
'';
};
services.avahi = {
enable = true;
nssmdns = true;
};
# Enable sound.
sound.enable = true;
hardware.pulseaudio = {
enable = true;
extraModules = [ pkgs.pulseaudio-modules-bt ];
package = pkgs.pulseaudioFull;
};
i18n.inputMethod = {
enabled = "fcitx";
fcitx.engines = with pkgs.fcitx-engines; [ table-extra m17n ];
};
fonts.fonts = [ pkgs.noto-fonts pkgs.noto-fonts-cjk pkgs.noto-fonts-emoji pkgs.noto-fonts-extra ];
# Enable the X11 windowing system.
services.xserver.enable = true;
services.xserver.layout = "us";
services.xserver.xkbOptions = "eurosign:e";
# Enable touchpad support.
services.xserver.libinput.enable = true;
services.xserver.displayManager.lightdm.enable = true;
services.xserver.desktopManager.xfce.enable = true;
programs.fish.enable = true;
programs.fish.promptInit = ''
fish-nix-shell --info-right | source
'';
users.mutableUsers = false;
users.defaultUserShell = pkgs.fish;
users.extraGroups.plugdev = { };
users.extraUsers = import ./common-users.nix { inherit pkgs; };
security.sudo.wheelNeedsPassword = false;
nix.binaryCachePublicKeys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
nix.binaryCaches = ["https://nixbld.m-labs.hk" "https://cache.nixos.org"];
nix.sandboxPaths = ["/opt"];
# This value determines the NixOS release with which your system is to be
# compatible, in order to avoid breaking some software such as database
# servers. You should change this only after NixOS release notes say you
# should.
system.stateVersion = "19.03"; # Did you read the comment?
}

View File

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

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, ... }: { config, pkgs, ... }:
let 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 in
{ {
deployment.targetHost = host; deployment.targetHost = host;
deployment.hasFastConnection = true;
nix.nixPath = [ "nixpkgs=${pkgs.path}" ];
programs.command-not-found.dbPath = "${pkgs.path}/programs.sqlite";
nixpkgs.system = "aarch64-linux"; nixpkgs.system = "aarch64-linux";
boot.loader.grub.enable = false; boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
boot.kernelParams = if rpi4 then ["cma=64M"] else []; # work around https://github.com/raspberrypi/linux/issues/3208
boot.initrd.includeDefaultModules = false;
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"; device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4"; fsType = "ext4";
@ -24,9 +34,7 @@ in
}; };
services.openssh.enable = true; services.openssh.enable = true;
services.openssh.authorizedKeysInHomedir = false; services.openssh.passwordAuthentication = false;
services.openssh.settings.PasswordAuthentication = false;
services.openssh.settings.GatewayPorts = "clientspecified";
services.openssh.extraConfig = services.openssh.extraConfig =
'' ''
StreamLocalBindUnlink yes StreamLocalBindUnlink yes
@ -34,41 +42,27 @@ in
programs.mosh.enable = true; programs.mosh.enable = true;
networking.hostName = host; networking.hostName = host;
time.timeZone = "Asia/Hong_Kong"; time.timeZone = "Asia/Hong_Kong";
users.extraGroups.plugdev = { }; users.extraGroups.plugdev = { };
users.mutableUsers = false; users.mutableUsers = false;
users.defaultUserShell = pkgs.fish; users.defaultUserShell = pkgs.fish;
users.extraUsers = (import ./common-users.nix { inherit pkgs; }) // { users.extraUsers = (import ./common-users.nix { inherit pkgs; }) // {
nixbld = { nix = {
isNormalUser = true; isNormalUser = true;
extraGroups = ["plugdev" "dialout"];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGJGICdNM9mHHAa1Cxk9Wz3YLkIEeqrIQGxM0aoy1g5O"
];
}; };
}; };
security.sudo.wheelNeedsPassword = false; security.sudo.wheelNeedsPassword = false;
services.udev.packages = [ artiq.packages.aarch64-linux.openocd-bscanspi ]; services.udev.packages = [ m-labs.openocd ];
services.udev.extraRules = (import ./extra-udev.nix);
documentation.enable = false; documentation.enable = false;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
psmisc wget vim git sshfs usbutils uhubctl lm_sensors file mosh tmux psmisc wget vim git usbutils lm_sensors file telnet mosh tmux xc3sprog m-labs.openocd screen gdb minicom picocom
artiq.packages.aarch64-linux.openocd-bscanspi
xc3sprog
screen gdb minicom picocom
]; ];
programs.zsh.enable = true;
programs.fish.enable = true; programs.fish.enable = true;
programs.wireshark.enable = true; programs.wireshark.enable = true;
nix.settings.trusted-public-keys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="]; nix.binaryCachePublicKeys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
nix.settings.substituters = ["https://nixbld.m-labs.hk?priority=10"]; nix.binaryCaches = ["https://cache.nixos.org" "https://nixbld.m-labs.hk"];
nix.settings.trusted-users = ["root" "sb"]; nix.trustedUsers = ["root" "nix"];
nix.extraOptions = ''
experimental-features = nix-command flakes impure-derivations
'';
} }

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

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