2024-02-20 22:16:23 +00:00
{ config , lib , . . . }:
2024-02-19 14:19:10 +00:00
let
declPackageSet = pkgs : {
packageUnwrapped = null ;
suggestedPrograms = pkgs ;
} ;
in
{
sane . programs = {
" s a n e - s c r i p t s . b a c k u p " = declPackageSet [
" s a n e - s c r i p t s . b a c k u p - l s "
" s a n e - s c r i p t s . b a c k u p - r e s t o r e "
] ;
" s a n e - s c r i p t s . b i t t o r r e n t " = declPackageSet [
" s a n e - s c r i p t s . b t - a d d "
" s a n e - s c r i p t s . b t - r m "
" s a n e - s c r i p t s . b t - s e a r c h "
" s a n e - s c r i p t s . b t - s h o w "
] ;
" s a n e - s c r i p t s . d e v " = declPackageSet [
" s a n e - s c r i p t s . c l o n e "
" s a n e - s c r i p t s . d e v - c a r g o - l o o p "
] ;
" s a n e - s c r i p t s . c l i " = declPackageSet [
" s a n e - s c r i p t s . d e a d l i n e s "
" s a n e - s c r i p t s . f i n d - d o t f i l e s "
" s a n e - s c r i p t s . i p - c h e c k "
" s a n e - s c r i p t s . p r i v a t e - c h a n g e - p a s s w d "
" s a n e - s c r i p t s . p r i v a t e - d o "
" s a n e - s c r i p t s . p r i v a t e - i n i t "
" s a n e - s c r i p t s . p r i v a t e - l o c k "
" s a n e - s c r i p t s . p r i v a t e - u n l o c k "
" s a n e - s c r i p t s . r c p "
" s a n e - s c r i p t s . r e b o o t "
" s a n e - s c r i p t s . r e c l a i m - b o o t - s p a c e "
" s a n e - s c r i p t s . r e c l a i m - d i s k - s p a c e "
" s a n e - s c r i p t s . s e c r e t s - d u m p "
" s a n e - s c r i p t s . s e c r e t s - u n l o c k "
" s a n e - s c r i p t s . s e c r e t s - u p d a t e - k e y s "
" s a n e - s c r i p t s . s h u t d o w n "
" s a n e - s c r i p t s . s u d o - r e d i r e c t "
" s a n e - s c r i p t s . t a g - m u s i c "
" s a n e - s c r i p t s . v p n "
" s a n e - s c r i p t s . w h i c h "
" s a n e - s c r i p t s . w i p e "
] ;
" s a n e - s c r i p t s . s y s - u t i l s " = declPackageSet [
" s a n e - s c r i p t s . i p - p o r t - f o r w a r d "
" s a n e - s c r i p t s . s y n c - m u s i c "
] ;
2024-02-19 16:51:53 +00:00
2024-02-28 13:19:39 +00:00
" s a n e - s c r i p t s . b a c k u p - l s " = { } ;
" s a n e - s c r i p t s . b a c k u p - r e s t o r e " = { } ;
2024-02-19 16:51:53 +00:00
" s a n e - s c r i p t s . b t - a d d " . sandbox = {
method = " b w r a p " ;
2024-04-03 09:42:01 +00:00
autodetectCliPaths = " e x i s t i n g " ; #< for adding a .torrent from disk
2024-02-19 16:51:53 +00:00
net = " c l e a r n e t " ;
# TODO: migrate `transmission_passwd` to `secrets` api
extraPaths = [ " / r u n / s e c r e t s / t r a n s m i s s i o n _ p a s s w d " ] ;
} ;
" s a n e - s c r i p t s . b t - r m " . sandbox = {
method = " b w r a p " ;
net = " c l e a r n e t " ;
# TODO: migrate `transmission_passwd` to `secrets` api
extraPaths = [ " / r u n / s e c r e t s / t r a n s m i s s i o n _ p a s s w d " ] ;
} ;
" s a n e - s c r i p t s . b t - s e a r c h " . sandbox = {
method = " b w r a p " ;
net = " c l e a r n e t " ;
# TODO: migrate `jackett_apikey` to `secrets` api
extraPaths = [ " / r u n / s e c r e t s / j a c k e t t _ a p i k e y " ] ;
} ;
" s a n e - s c r i p t s . b t - s h o w " . sandbox = {
method = " b w r a p " ;
net = " c l e a r n e t " ;
# TODO: migrate `transmission_passwd` to `secrets` api
extraPaths = [ " / r u n / s e c r e t s / t r a n s m i s s i o n _ p a s s w d " ] ;
} ;
# the idea of this script is to `cd` into a fresh clone...
# but that's an ephemeral operation that would be lost when the sandbox closes.
" s a n e - s c r i p t s . c l o n e " . sandbox . enable = false ;
" s a n e - s c r i p t s . d e a d l i n e s " . sandbox = {
method = " b w r a p " ;
extraHomePaths = [ " k n o w l e d g e / p l a n n e r / d e a d l i n e s . t s v " ] ;
} ;
2024-02-20 19:26:38 +00:00
" s a n e - s c r i p t s . d e v - c a r g o - l o o p " . sandbox = {
method = " b w r a p " ;
net = " c l e a r n e t " ;
whitelistPwd = true ;
extraPaths = [
# a build script can do a lot... but a well-written one will be confined
# to XDG dirs and the local dir, and maybe the internet for fetching dependencies.
" . c a c h e "
" . c o n f i g "
" . l o c a l "
] ;
} ;
2024-02-19 16:51:53 +00:00
" s a n e - s c r i p t s . f i n d - d o t f i l e s " . sandbox = {
method = " b w r a p " ;
extraHomePaths = [
2024-02-23 06:43:27 +00:00
" / "
" . p e r s i s t / e p h e m e r a l "
" . p e r s i s t / p l a i n t e x t "
2024-02-19 16:51:53 +00:00
] ;
} ;
" s a n e - s c r i p t s . i p - c h e c k " . sandbox = {
2024-02-20 23:05:24 +00:00
method = " l a n d l o c k " ;
net = " a l l " ;
2024-02-19 16:51:53 +00:00
} ;
2024-02-28 13:19:39 +00:00
" s a n e - s c r i p t s . i p - p o r t - f o r w a r d " = { } ;
2024-02-25 16:35:13 +00:00
" s a n e - s c r i p t s . p r i v a t e - c h a n g e - p a s s w d " . sandbox = {
method = " b w r a p " ;
autodetectCliPaths = " e x i s t i n g " ; #< for the new `private` location
capabilities = [ " s y s _ a d m i n " ] ; # it needs to mount the new store
extraHomePaths = [
" . p e r s i s t / p r i v a t e "
] ;
} ;
2024-02-25 05:29:28 +00:00
" s a n e - s c r i p t s . p r i v a t e - d o " . sandbox = {
# because `mount` is a cap_sys_admin syscall, there's no great way to mount stuff dynamically like this.
# instead, we put ourselves in a mount namespace, do the mount, and drop into a shell or run a command.
# this actually has an OK side effect, that the mount isn't shared, and so we avoid contention/interleaving that would cause the ending `umount` to fail.
method = " b w r a p " ;
# cap_sys_admin is needed to mount stuff.
# ordinarily /run/wrappers/bin/mount would do that via setuid, but sandboxes have no_new_privs by default.
capabilities = [ " s y s _ a d m i n " ] ;
# `sane-private-do` acts as a launcher, so give it access to anything it could possibly need.
# (crucially, that includes the backing store)
2024-02-25 08:25:13 +00:00
net = " a l l " ;
2024-02-25 05:29:28 +00:00
extraPaths = [ " / " ] ;
} ;
2024-02-25 16:46:10 +00:00
" s a n e - s c r i p t s . p r i v a t e - i n i t " . sandbox = {
method = " b w r a p " ;
capabilities = [ " s y s _ a d m i n " ] ; # it needs to mount the new store
extraHomePaths = [
" . p e r s i s t / p r i v a t e "
] ;
} ;
2024-02-25 05:29:28 +00:00
" s a n e - s c r i p t s . p r i v a t e - l o c k " . sandbox . enable = false ;
" s a n e - s c r i p t s . p r i v a t e - u n l o c k " . sandbox . enable = false ;
2024-02-20 23:31:39 +00:00
2024-02-20 19:16:36 +00:00
" s a n e - s c r i p t s . r e c l a i m - b o o t - s p a c e " . sandbox = {
method = " b w r a p " ;
extraPaths = [ " / b o o t " ] ;
} ;
2024-02-19 17:06:22 +00:00
2024-02-20 13:43:05 +00:00
# it's just a thin wrapper around rsync, which is already sandboxed
" s a n e - s c r i p t s . r c p " . sandbox . enable = false ;
# but make sure rsync is always on PATH, so that we actually do get sandboxing :)
" s a n e - s c r i p t s . r c p " . suggestedPrograms = [ " r s y n c " ] ;
" s a n e - s c r i p t s . r e b o o t " . sandbox = {
method = " b w r a p " ;
extraPaths = [
" / r u n / d b u s "
" / r u n / s y s t e m d "
] ;
} ;
2024-02-19 17:06:22 +00:00
" s a n e - s c r i p t s . r e c l a i m - d i s k - s p a c e " . sandbox = {
method = " b w r a p " ;
extraPaths = [ " / n i x / v a r / n i x " ] ;
} ;
2024-02-20 23:31:39 +00:00
" s a n e - s c r i p t s . s e c r e t s - u n l o c k " . sandbox = {
method = " b w r a p " ;
extraHomePaths = [
" . s s h / i d _ e d 2 5 5 1 9 "
" . s s h / i d _ e d 2 5 5 1 9 . p u b "
" . c o n f i g / s o p s "
] ;
} ;
# sane-secrets-dump is a thin wrapper around sops + some utilities.
# really i should sandbox just the utilities
" s a n e - s c r i p t s . s e c r e t s - d u m p " . sandbox . enable = false ;
" s a n e - s c r i p t s . s e c r e t s - d u m p " . suggestedPrograms = [
" g n u g r e p "
" o a t h - t o o l k i t "
" s o p s "
] ;
# sane-secrets-update-keys is a thin wrapper around sops + some utilities.
# really i should sandbox just the utilities
" s a n e - s c r i p t s . s e c r e t s - u p d a t e - k e y s " . sandbox . enable = false ;
" s a n e - s c r i p t s . s e c r e t s - u p d a t e - k e y s " . suggestedPrograms = [
" f i n d u t i l s "
" s o p s "
] ;
2024-02-20 13:43:05 +00:00
" s a n e - s c r i p t s . s h u t d o w n " . sandbox = {
method = " b w r a p " ;
extraPaths = [
" / r u n / d b u s "
" / r u n / s y s t e m d "
] ;
} ;
2024-02-28 13:19:39 +00:00
" s a n e - s c r i p t s . s t o p - a l l - s e r v o " = { } ;
2024-02-19 17:09:27 +00:00
# if `tee` isn't trustworthy we have bigger problems
" s a n e - s c r i p t s . s u d o - r e d i r e c t " . sandbox . enable = false ;
2024-02-28 13:19:39 +00:00
" s a n e - s c r i p t s . s y n c - m u s i c " = { } ;
" s a n e - s c r i p t s . s y n c - f r o m - i p h o n e " = { } ;
2024-02-20 19:26:18 +00:00
" s a n e - s c r i p t s . t a g - m u s i c " . sandbox = {
method = " b w r a p " ;
autodetectCliPaths = " e x i s t i n g " ;
} ;
2024-02-20 22:16:23 +00:00
" s a n e - s c r i p t s . v p n " . fs = lib . foldl'
( acc : vpn :
let
vpnCfg = config . sane . vpn . " ${ vpn } " ;
in acc // {
" . c o n f i g / s a n e - v p n / v p n s / ${ vpn } " . symlink . text = ''
id = $ { builtins . toString vpnCfg . id }
fwmark = $ { builtins . toString vpnCfg . fwmark }
priorityMain = $ { builtins . toString vpnCfg . priorityMain }
priorityFwMark = $ { builtins . toString vpnCfg . priorityFwMark }
bridgeDevice = $ { vpnCfg . bridgeDevice }
dns = ( $ { lib . concatStringsSep " " vpnCfg . dns } )
'' ;
} // ( lib . optionalAttrs vpnCfg . isDefault {
" . c o n f i g / s a n e - v p n / d e f a u l t " . symlink . text = vpn ;
} )
)
{ }
( builtins . attrNames config . sane . vpn ) ;
2024-02-20 23:05:24 +00:00
" s a n e - s c r i p t s . v p n " . sandbox = {
method = " l a n d l o c k " ; #< bwrap can't handle `ip link` stuff even with cap_net_admin
net = " a l l " ;
capabilities = [ " n e t _ a d m i n " ] ;
extraHomePaths = [ " . c o n f i g / s a n e - v p n " ] ;
} ;
2024-02-20 22:16:23 +00:00
2024-02-19 16:51:53 +00:00
" s a n e - s c r i p t s . w h i c h " . sandbox = {
method = " b w r a p " ;
extraHomePaths = [
# for SXMO
" . c o n f i g / s x m o / h o o k s "
] ;
} ;
" s a n e - s c r i p t s . w i p e " . sandbox = {
method = " b w r a p " ;
2024-03-26 16:57:30 +00:00
whitelistDbus = [ " u s e r " ] ; #< for `secret-tool`
whitelistS6 = true ; #< for stopping services before wiping
2024-02-19 16:51:53 +00:00
extraHomePaths = [
# could be more specific, but at a maintenance cost.
2024-02-23 06:43:27 +00:00
# TODO: needs updating, now that persisted data lives behind symlinks!
# both this list AND the script need patching for that.
2024-02-19 16:51:53 +00:00
" . c a c h e "
" . c o n f i g "
" . l o c a l / s h a r e "
" . l i b r e w o l f "
" . m o z i l l a "
2024-03-06 05:11:24 +00:00
" . p e r s i s t / e p h e m e r a l / . c a c h e "
" . p e r s i s t / e p h e m e r a l / . c o n f i g "
" . p e r s i s t / e p h e m e r a l / . l o c a l / s h a r e "
" . p e r s i s t / e p h e m e r a l / . l i b r e w o l f "
" . p e r s i s t / e p h e m e r a l / . m o z i l l a "
" . p e r s i s t / p l a i n t e x t / . c a c h e "
" . p e r s i s t / p l a i n t e x t / . c o n f i g "
" . p e r s i s t / p l a i n t e x t / . l o c a l / s h a r e "
" . p e r s i s t / p l a i n t e x t / . l i b r e w o l f "
" . p e r s i s t / p l a i n t e x t / . m o z i l l a "
" . p e r s i s t / p r i v a t e / . c a c h e "
" . p e r s i s t / p r i v a t e / . c o n f i g "
" . p e r s i s t / p r i v a t e / . l o c a l / s h a r e "
" . p e r s i s t / p r i v a t e / . l i b r e w o l f "
" . p e r s i s t / p r i v a t e / . m o z i l l a "
2024-02-19 16:51:53 +00:00
] ;
} ;
2024-02-19 14:19:10 +00:00
} ;
}