Development discussion of WireGuard
 help / color / mirror / Atom feed
* [PATCH] wg-quick: add 'reload' command (wrapper for 'wg syncconf')
@ 2020-03-30  8:41 Tore Anderson
  2020-04-10  9:42 ` Guy Godfroy
  2020-06-02 13:09 ` Tore Anderson
  0 siblings, 2 replies; 3+ messages in thread
From: Tore Anderson @ 2020-03-30  8:41 UTC (permalink / raw)
  To: wireguard; +Cc: Tore Anderson

Also add an ExecReload statement that uses this in the systemd template unit.

Signed-off-by: Tore Anderson <tore@fud.no>
---
 src/man/wg-quick.8            |  9 ++++++---
 src/systemd/wg-quick@.service |  1 +
 src/wg-quick/darwin.bash      | 17 ++++++++++++++++-
 src/wg-quick/freebsd.bash     | 15 ++++++++++++++-
 src/wg-quick/linux.bash       | 15 ++++++++++++++-
 src/wg-quick/openbsd.bash     | 15 ++++++++++++++-
 6 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/src/man/wg-quick.8 b/src/man/wg-quick.8
index eca3b48..023805e 100644
--- a/src/man/wg-quick.8
+++ b/src/man/wg-quick.8
@@ -10,6 +10,8 @@ wg-quick - set up a WireGuard interface simply
 |
 .I down
 |
+.I reload
+|
 .I save
 |
 .I strip
@@ -28,9 +30,10 @@ Use \fIup\fP to add and set up an interface, and use \fIdown\fP to tear down and
 an interface. Running \fIup\fP adds a WireGuard interface, brings up the interface with the
 supplied IP addresses, sets up mtu and routes, and optionally runs pre/post up scripts. Running \fIdown\fP
 optionally saves the current configuration, removes the WireGuard interface, and optionally
-runs pre/post down scripts. Running \fIsave\fP saves the configuration of an existing
-interface without bringing the interface down. Use \fIstrip\fP to output a configuration file
-with all
+runs pre/post down scripts. Running \fIreload\fP synchronises any changes to peers/keys in
+the config file with an already active interfaces. Running \fIsave\fP saves the configuration
+of an existing interface without bringing the interface down. Use \fIstrip\fP to output a
+configuration file with all
 .BR wg-quick (8)-specific
 options removed, suitable for use with
 .BR wg (8).
diff --git a/src/systemd/wg-quick@.service b/src/systemd/wg-quick@.service
index 7c5f9d1..a3b89d9 100644
--- a/src/systemd/wg-quick@.service
+++ b/src/systemd/wg-quick@.service
@@ -14,6 +14,7 @@ Type=oneshot
 RemainAfterExit=yes
 ExecStart=/usr/bin/wg-quick up %i
 ExecStop=/usr/bin/wg-quick down %i
+ExecReload=/usr/bin/wg-quick reload %i
 Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity
 
 [Install]
diff --git a/src/wg-quick/darwin.bash b/src/wg-quick/darwin.bash
index d9d07cf..a732d6a 100755
--- a/src/wg-quick/darwin.bash
+++ b/src/wg-quick/darwin.bash
@@ -350,6 +350,10 @@ set_config() {
 	cmd wg setconf "$REAL_INTERFACE" <(echo "$WG_CONFIG")
 }
 
+sync_config() {
+	cmd wg syncconf "$REAL_INTERFACE" <(echo "$WG_CONFIG")
+}
+
 save_config() {
 	local old_umask new_config current_config address cmd
 	new_config=$'[Interface]\n'
@@ -398,7 +402,7 @@ execute_hooks() {
 
 cmd_usage() {
 	cat >&2 <<-_EOF
-	Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
+	Usage: $PROGRAM [ up | down | reload | save | strip ] [ CONFIG_FILE | INTERFACE ]
 
 	  CONFIG_FILE is a configuration file, whose filename is the interface name
 	  followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
@@ -458,6 +462,13 @@ cmd_down() {
 	execute_hooks "${POST_DOWN[@]}"
 }
 
+cmd_reload() {
+	if ! get_real_interface || [[ " $(wg show interfaces) " != *" $REAL_INTERFACE "* ]]; then
+		die "\`$INTERFACE' is not a WireGuard interface"
+	fi
+	sync_config
+}
+
 cmd_save() {
 	if ! get_real_interface || [[ " $(wg show interfaces) " != *" $REAL_INTERFACE "* ]]; then
 		die "\`$INTERFACE' is not a WireGuard interface"
@@ -482,6 +493,10 @@ elif [[ $# -eq 2 && $1 == down ]]; then
 	auto_su
 	parse_options "$2"
 	cmd_down
+elif [[ $# -eq 2 && $1 == reload ]]; then
+	auto_su
+	parse_options "$2"
+	cmd_reload
 elif [[ $# -eq 2 && $1 == save ]]; then
 	auto_su
 	parse_options "$2"
diff --git a/src/wg-quick/freebsd.bash b/src/wg-quick/freebsd.bash
index c390dcc..6eef1f6 100755
--- a/src/wg-quick/freebsd.bash
+++ b/src/wg-quick/freebsd.bash
@@ -333,6 +333,10 @@ set_config() {
 	cmd wg setconf "$INTERFACE" <(echo "$WG_CONFIG")
 }
 
+sync_config() {
+	cmd wg syncconf "$INTERFACE" <(echo "$WG_CONFIG")
+}
+
 save_config() {
 	local old_umask new_config current_config address cmd
 	new_config=$'[Interface]\n'
@@ -382,7 +386,7 @@ execute_hooks() {
 
 cmd_usage() {
 	cat >&2 <<-_EOF
-	Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
+	Usage: $PROGRAM [ up | down | reload | save | strip ] [ CONFIG_FILE | INTERFACE ]
 
 	  CONFIG_FILE is a configuration file, whose filename is the interface name
 	  followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
@@ -440,6 +444,11 @@ cmd_down() {
 	execute_hooks "${POST_DOWN[@]}"
 }
 
+cmd_reload() {
+	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
+	sync_config
+}
+
 cmd_save() {
 	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
 	save_config
@@ -464,6 +473,10 @@ elif [[ $# -eq 2 && $1 == down ]]; then
 	auto_su
 	parse_options "$2"
 	cmd_down
+elif [[ $# -eq 2 && $1 == reload ]]; then
+	auto_su
+	parse_options "$2"
+	cmd_reload
 elif [[ $# -eq 2 && $1 == save ]]; then
 	auto_su
 	parse_options "$2"
diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash
index 7c2c002..37d6ba8 100755
--- a/src/wg-quick/linux.bash
+++ b/src/wg-quick/linux.bash
@@ -246,6 +246,10 @@ set_config() {
 	cmd wg setconf "$INTERFACE" <(echo "$WG_CONFIG")
 }
 
+sync_config() {
+	cmd wg syncconf "$INTERFACE" <(echo "$WG_CONFIG")
+}
+
 save_config() {
 	local old_umask new_config current_config address cmd
 	[[ $(ip -all -brief address show dev "$INTERFACE") =~ ^$INTERFACE\ +\ [A-Z]+\ +(.+)$ ]] || true
@@ -293,7 +297,7 @@ execute_hooks() {
 
 cmd_usage() {
 	cat >&2 <<-_EOF
-	Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
+	Usage: $PROGRAM [ up | down | reload | save | strip ] [ CONFIG_FILE | INTERFACE ]
 
 	  CONFIG_FILE is a configuration file, whose filename is the interface name
 	  followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
@@ -347,6 +351,11 @@ cmd_down() {
 	execute_hooks "${POST_DOWN[@]}"
 }
 
+cmd_reload() {
+	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
+	sync_config
+}
+
 cmd_save() {
 	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
 	save_config
@@ -368,6 +377,10 @@ elif [[ $# -eq 2 && $1 == down ]]; then
 	auto_su
 	parse_options "$2"
 	cmd_down
+elif [[ $# -eq 2 && $1 == reload ]]; then
+	auto_su
+	parse_options "$2"
+	cmd_reload
 elif [[ $# -eq 2 && $1 == save ]]; then
 	auto_su
 	parse_options "$2"
diff --git a/src/wg-quick/openbsd.bash b/src/wg-quick/openbsd.bash
index 8d458d1..c509e70 100755
--- a/src/wg-quick/openbsd.bash
+++ b/src/wg-quick/openbsd.bash
@@ -313,6 +313,10 @@ set_config() {
 	cmd wg setconf "$REAL_INTERFACE" <(echo "$WG_CONFIG")
 }
 
+sync_config() {
+	cmd wg syncconf "$INTERFACE" <(echo "$WG_CONFIG")
+}
+
 save_config() {
 	local old_umask new_config current_config address network cmd
 	new_config=$'[Interface]\n'
@@ -361,7 +365,7 @@ execute_hooks() {
 
 cmd_usage() {
 	cat >&2 <<-_EOF
-	Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
+	Usage: $PROGRAM [ up | down | reload | save | strip ] [ CONFIG_FILE | INTERFACE ]
 
 	  CONFIG_FILE is a configuration file, whose filename is the interface name
 	  followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
@@ -419,6 +423,11 @@ cmd_down() {
 	execute_hooks "${POST_DOWN[@]}"
 }
 
+cmd_reload() {
+	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
+	sync_config
+}
+
 cmd_save() {
 	if ! get_real_interface || [[ " $(wg show interfaces) " != *" $REAL_INTERFACE "* ]]; then
 		die "\`$INTERFACE' is not a WireGuard interface"
@@ -442,6 +451,10 @@ elif [[ $# -eq 2 && $1 == down ]]; then
 	auto_su
 	parse_options "$2"
 	cmd_down
+elif [[ $# -eq 2 && $1 == reload ]]; then
+	auto_su
+	parse_options "$2"
+	cmd_reload
 elif [[ $# -eq 2 && $1 == save ]]; then
 	auto_su
 	parse_options "$2"
-- 
2.25.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] wg-quick: add 'reload' command (wrapper for 'wg syncconf')
  2020-03-30  8:41 [PATCH] wg-quick: add 'reload' command (wrapper for 'wg syncconf') Tore Anderson
@ 2020-04-10  9:42 ` Guy Godfroy
  2020-06-02 13:09 ` Tore Anderson
  1 sibling, 0 replies; 3+ messages in thread
From: Guy Godfroy @ 2020-04-10  9:42 UTC (permalink / raw)
  To: wireguard

Hello,

I wish this patch could be merged. This would make stuff easier, cleaner 
and consistent with a lot of other services.

Guy Godfroy

Le 30/03/2020 à 10:41, Tore Anderson a écrit :
> Also add an ExecReload statement that uses this in the systemd template unit.
> 
> Signed-off-by: Tore Anderson <tore@fud.no>
> ---
>   src/man/wg-quick.8            |  9 ++++++---
>   src/systemd/wg-quick@.service |  1 +
>   src/wg-quick/darwin.bash      | 17 ++++++++++++++++-
>   src/wg-quick/freebsd.bash     | 15 ++++++++++++++-
>   src/wg-quick/linux.bash       | 15 ++++++++++++++-
>   src/wg-quick/openbsd.bash     | 15 ++++++++++++++-
>   6 files changed, 65 insertions(+), 7 deletions(-)
> 
> diff --git a/src/man/wg-quick.8 b/src/man/wg-quick.8reload
> index eca3b48..023805e 100644
> --- a/src/man/wg-quick.8
> +++ b/src/man/wg-quick.8
> @@ -10,6 +10,8 @@ wg-quick - set up a WireGuard interface simply
>   |
>   .I down
>   |
> +.I reload
> +|
>   .I save
>   |
>   .I strip
> @@ -28,9 +30,10 @@ Use \fIup\fP to add and set up an interface, and use \fIdown\fP to tear down and
>   an interface. Running \fIup\fP adds a WireGuard interface, brings up the interface with the
>   supplied IP addresses, sets up mtu and routes, and optionally runs pre/post up scripts. Running \fIdown\fP
>   optionally saves the current configuration, removes the WireGuard interface, and optionally
> -runs pre/post down scripts. Running \fIsave\fP saves the configuration of an existing
> -interface without bringing the interface down. Use \fIstrip\fP to output a configuration file
> -with all
> +runs pre/post down scripts. Running \fIreload\fP synchronises any changes to peers/keys in
> +the config file with an already active interfaces. Running \fIsave\fP saves the configuration
> +of an existing interface without bringing the interface down. Use \fIstrip\fP to output a
> +configuration file with all
>   .BR wg-quick (8)-specific
>   options removed, suitable for use with
>   .BR wg (8).
> diff --git a/src/systemd/wg-quick@.service b/src/systemd/wg-quick@.service
> index 7c5f9d1..a3b89d9 100644
> --- a/src/systemd/wg-quick@.service
> +++ b/src/systemd/wg-quick@.service
> @@ -14,6 +14,7 @@ Type=oneshot
>   RemainAfterExit=yes
>   ExecStart=/usr/bin/wg-quick up %i
>   ExecStop=/usr/bin/wg-quick down %i
> +ExecReload=/usr/bin/wg-quick reload %i
>   Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity
>   
>   [Install]
> diff --git a/src/wg-quick/darwin.bash b/src/wg-quick/darwin.bash
> index d9d07cf..a732d6a 100755
> --- a/src/wg-quick/darwin.bash
> +++ b/src/wg-quick/darwin.bash
> @@ -350,6 +350,10 @@ set_config() {
>   	cmd wg setconf "$REAL_INTERFACE" <(echo "$WG_CONFIG")
>   }
>   
> +sync_config() {
> +	cmd wg syncconf "$REAL_INTERFACE" <(echo "$WG_CONFIG")
> +}
> +
>   save_config() {
>   	local old_umask new_config current_config address cmd
>   	new_config=$'[Interface]\n'
> @@ -398,7 +402,7 @@ execute_hooks() {
>   
>   cmd_usage() {
>   	cat >&2 <<-_EOF
> -	Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
> +	Usage: $PROGRAM [ up | down | reload | save | strip ] [ CONFIG_FILE | INTERFACE ]
>   
>   	  CONFIG_FILE is a configuration file, whose filename is the interface name
>   	  followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
> @@ -458,6 +462,13 @@ cmd_down() {
>   	execute_hooks "${POST_DOWN[@]}"
>   }
>   
> +cmd_reload() {
> +	if ! get_real_interface || [[ " $(wg show interfaces) " != *" $REAL_INTERFACE "* ]]; then
> +		die "\`$INTERFACE' is not a WireGuard interface"
> +	fi
> +	sync_config
> +}
> +
>   cmd_save() {
>   	if ! get_real_interface || [[ " $(wg show interfaces) " != *" $REAL_INTERFACE "* ]]; then
>   		die "\`$INTERFACE' is not a WireGuard interface"
> @@ -482,6 +493,10 @@ elif [[ $# -eq 2 && $1 == down ]]; then
>   	auto_su
>   	parse_options "$2"
>   	cmd_down
> +elif [[ $# -eq 2 && $1 == reload ]]; then
> +	auto_su
> +	parse_options "$2"
> +	cmd_reload
>   elif [[ $# -eq 2 && $1 == save ]]; then
>   	auto_su
>   	parse_options "$2"
> diff --git a/src/wg-quick/freebsd.bash b/src/wg-quick/freebsd.bash
> index c390dcc..6eef1f6 100755
> --- a/src/wg-quick/freebsd.bash
> +++ b/src/wg-quick/freebsd.bash
> @@ -333,6 +333,10 @@ set_config() {
>   	cmd wg setconf "$INTERFACE" <(echo "$WG_CONFIG")
>   }
>   
> +sync_config() {
> +	cmd wg syncconf "$INTERFACE" <(echo "$WG_CONFIG")
> +}
> +
>   save_config() {
>   	local old_umask new_config current_config address cmd
>   	new_config=$'[Interface]\n'
> @@ -382,7 +386,7 @@ execute_hooks() {
>   
>   cmd_usage() {
>   	cat >&2 <<-_EOF
> -	Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
> +	Usage: $PROGRAM [ up | down | reload | save | strip ] [ CONFIG_FILE | INTERFACE ]
>   
>   	  CONFIG_FILE is a configuration file, whose filename is the interface name
>   	  followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
> @@ -440,6 +444,11 @@ cmd_down() {
>   	execute_hooks "${POST_DOWN[@]}"
>   }
>   
> +cmd_reload() {
> +	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
> +	sync_config
> +}
> +
>   cmd_save() {
>   	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
>   	save_config
> @@ -464,6 +473,10 @@ elif [[ $# -eq 2 && $1 == down ]]; then
>   	auto_su
>   	parse_options "$2"
>   	cmd_down
> +elif [[ $# -eq 2 && $1 == reload ]]; then
> +	auto_su
> +	parse_options "$2"
> +	cmd_reload
>   elif [[ $# -eq 2 && $1 == save ]]; then
>   	auto_su
>   	parse_options "$2"
> diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash
> index 7c2c002..37d6ba8 100755
> --- a/src/wg-quick/linux.bash
> +++ b/src/wg-quick/linux.bash
> @@ -246,6 +246,10 @@ set_config() {
>   	cmd wg setconf "$INTERFACE" <(echo "$WG_CONFIG")
>   }
>   
> +sync_config() {
> +	cmd wg syncconf "$INTERFACE" <(echo "$WG_CONFIG")
> +}
> +
>   save_config() {
>   	local old_umask new_config current_config address cmd
>   	[[ $(ip -all -brief address show dev "$INTERFACE") =~ ^$INTERFACE\ +\ [A-Z]+\ +(.+)$ ]] || true
> @@ -293,7 +297,7 @@ execute_hooks() {
>   
>   cmd_usage() {
>   	cat >&2 <<-_EOF
> -	Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
> +	Usage: $PROGRAM [ up | down | reload | save | strip ] [ CONFIG_FILE | INTERFACE ]
>   
>   	  CONFIG_FILE is a configuration file, whose filename is the interface name
>   	  followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
> @@ -347,6 +351,11 @@ cmd_down() {
>   	execute_hooks "${POST_DOWN[@]}"
>   }
>   
> +cmd_reload() {
> +	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
> +	sync_config
> +}
> +
>   cmd_save() {
>   	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
>   	save_config
> @@ -368,6 +377,10 @@ elif [[ $# -eq 2 && $1 == down ]]; then
>   	auto_su
>   	parse_options "$2"
>   	cmd_down
> +elif [[ $# -eq 2 && $1 == reload ]]; then
> +	auto_su
> +	parse_options "$2"
> +	cmd_reload
>   elif [[ $# -eq 2 && $1 == save ]]; then
>   	auto_su
>   	parse_options "$2"
> diff --git a/src/wg-quick/openbsd.bash b/src/wg-quick/openbsd.bash
> index 8d458d1..c509e70 100755
> --- a/src/wg-quick/openbsd.bash
> +++ b/src/wg-quick/openbsd.bash
> @@ -313,6 +313,10 @@ set_config() {
>   	cmd wg setconf "$REAL_INTERFACE" <(echo "$WG_CONFIG")
>   }
>   
> +sync_config() {
> +	cmd wg syncconf "$INTERFACE" <(echo "$WG_CONFIG")
> +}
> +
>   save_config() {
>   	local old_umask new_config current_config address network cmd
>   	new_config=$'[Interface]\n'
> @@ -361,7 +365,7 @@ execute_hooks() {
>   
>   cmd_usage() {
>   	cat >&2 <<-_EOF
> -	Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
> +	Usage: $PROGRAM [ up | down | reload | save | strip ] [ CONFIG_FILE | INTERFACE ]
>   
>   	  CONFIG_FILE is a configuration file, whose filename is the interface name
>   	  followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
> @@ -419,6 +423,11 @@ cmd_down() {
>   	execute_hooks "${POST_DOWN[@]}"
>   }
>   
> +cmd_reload() {
> +	[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
> +	sync_config
> +}
> +
>   cmd_save() {
>   	if ! get_real_interface || [[ " $(wg show interfaces) " != *" $REAL_INTERFACE "* ]]; then
>   		die "\`$INTERFACE' is not a WireGuard interface"
> @@ -442,6 +451,10 @@ elif [[ $# -eq 2 && $1 == down ]]; then
>   	auto_su
>   	parse_options "$2"
>   	cmd_down
> +elif [[ $# -eq 2 && $1 == reload ]]; then
> +	auto_su
> +	parse_options "$2"
> +	cmd_reload
>   elif [[ $# -eq 2 && $1 == save ]]; then
>   	auto_su
>   	parse_options "$2"
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] wg-quick: add 'reload' command (wrapper for 'wg syncconf')
  2020-03-30  8:41 [PATCH] wg-quick: add 'reload' command (wrapper for 'wg syncconf') Tore Anderson
  2020-04-10  9:42 ` Guy Godfroy
@ 2020-06-02 13:09 ` Tore Anderson
  1 sibling, 0 replies; 3+ messages in thread
From: Tore Anderson @ 2020-06-02 13:09 UTC (permalink / raw)
  To: wireguard

* Tore Anderson

> Also add an ExecReload statement that uses this in the systemd template unit.

Hello maintainers,

I hate to nag, but considering this patch was posted over two months
ago now and has yet to receive any feedback from any maintainer - good
or bad - I am starting to suspect it has been forgotten about. Has it?

If there are outstanding issues with the patch that needs to be
resolved before it can be merged, please let me know what those are and
I will try to post a PATCH v2.

Tore


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-06-02 13:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-30  8:41 [PATCH] wg-quick: add 'reload' command (wrapper for 'wg syncconf') Tore Anderson
2020-04-10  9:42 ` Guy Godfroy
2020-06-02 13:09 ` Tore Anderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).