forked from pub-solar/infra
Merge pull request 'forgejo: allow multiple host addresses for SSH' (#133) from fix/forgejo-multi-host into main
Reviewed-on: pub-solar/infra#133 Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
This commit is contained in:
commit
ae0c90e4f8
|
@ -26,4 +26,15 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.openssh.listenAddresses = [
|
||||||
|
{
|
||||||
|
addr = "10.7.6.2";
|
||||||
|
port = 22;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
addr = "[fd00:fae:fae:fae:fae:2::]";
|
||||||
|
port = 22;
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,11 +41,16 @@
|
||||||
|
|
||||||
users.groups.gitea = {};
|
users.groups.gitea = {};
|
||||||
|
|
||||||
|
# Expose SSH port only for forgejo SSH
|
||||||
|
networking.firewall.interfaces.enp35s0.allowedTCPPorts = [ 22 ];
|
||||||
|
|
||||||
services.forgejo = {
|
services.forgejo = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = "gitea";
|
user = "gitea";
|
||||||
group = "gitea";
|
group = "gitea";
|
||||||
package = pkgs.forgejo;
|
package = pkgs.forgejo.overrideAttrs (o: {
|
||||||
|
patches = (o.patches or [ ]) ++ [ ./multiple-ssh-host.patch ];
|
||||||
|
});
|
||||||
database = {
|
database = {
|
||||||
type = "postgres";
|
type = "postgres";
|
||||||
passwordFile = config.age.secrets.forgejo-database-password.path;
|
passwordFile = config.age.secrets.forgejo-database-password.path;
|
||||||
|
@ -63,6 +68,8 @@
|
||||||
DOMAIN = "git.pub.solar";
|
DOMAIN = "git.pub.solar";
|
||||||
HTTP_ADDR = "127.0.0.1";
|
HTTP_ADDR = "127.0.0.1";
|
||||||
HTTP_PORT = 3000;
|
HTTP_PORT = 3000;
|
||||||
|
START_SSH_SERVER = true;
|
||||||
|
SSH_LISTEN_HOST = "138.201.80.102,[2a01:4f8:172:1c25::1]";
|
||||||
};
|
};
|
||||||
|
|
||||||
log.LEVEL = "Warn";
|
log.LEVEL = "Warn";
|
131
hosts/nachtigall/apps/forgejo/multiple-ssh-host.patch
Normal file
131
hosts/nachtigall/apps/forgejo/multiple-ssh-host.patch
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md
|
||||||
|
index 16e1e8223a..54d710b3d7 100644
|
||||||
|
--- a/docs/content/administration/config-cheat-sheet.en-us.md
|
||||||
|
+++ b/docs/content/administration/config-cheat-sheet.en-us.md
|
||||||
|
@@ -327,7 +327,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
|
- `SSH_USER`: **%(BUILTIN_SSH_SERVER_USER)s**: SSH username displayed in clone URLs. This is only for people who configure the SSH server themselves; in most cases, you want to leave this blank and modify the `BUILTIN_SSH_SERVER_USER`.
|
||||||
|
- `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL.
|
||||||
|
- `SSH_PORT`: **22**: SSH port displayed in clone URL.
|
||||||
|
-- `SSH_LISTEN_HOST`: **0.0.0.0**: Listen address for the built-in SSH server.
|
||||||
|
+- `SSH_LISTEN_HOST`: **0.0.0.0**: Listen address(es) for the built-in SSH server; multiple addresses can be separated by comma, addresses can include a port statement to override SSH_LISTEN_PORT.
|
||||||
|
- `SSH_LISTEN_PORT`: **%(SSH\_PORT)s**: Port for the built-in SSH server.
|
||||||
|
- `SSH_ROOT_PATH`: **~/.ssh**: Root path of SSH directory.
|
||||||
|
- `SSH_CREATE_AUTHORIZED_KEYS_FILE`: **true**: Gitea will create a authorized_keys file by default when it is not using the internal ssh server. If you intend to use the AuthorizedKeysCommand functionality then you should turn this off.
|
||||||
|
diff --git a/modules/graceful/manager.go b/modules/graceful/manager.go
|
||||||
|
index 068de21076..1e1a8239e8 100644
|
||||||
|
--- a/modules/graceful/manager.go
|
||||||
|
+++ b/modules/graceful/manager.go
|
||||||
|
@@ -272,6 +272,12 @@ func (g *Manager) InformCleanup() {
|
||||||
|
g.createServerWaitGroup.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Should we need to create multile listener for one type (e.g. SSH built-in server),
|
||||||
|
+// the number of expected routines needs to be increased accordingly.
|
||||||
|
+func (g *Manager) IncreaseListenerCountBy(extraNumberOfServersToCreate int) {
|
||||||
|
+ g.createServerWaitGroup.Add(extraNumberOfServersToCreate)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// Done allows the manager to be viewed as a context.Context, it returns a channel that is closed when the server is finished terminating
|
||||||
|
func (g *Manager) Done() <-chan struct{} {
|
||||||
|
return g.managerCtx.Done()
|
||||||
|
diff --git a/modules/setting/ssh.go b/modules/setting/ssh.go
|
||||||
|
index a5a9da0b36..e73aa0115a 100644
|
||||||
|
--- a/modules/setting/ssh.go
|
||||||
|
+++ b/modules/setting/ssh.go
|
||||||
|
@@ -25,7 +25,7 @@ var SSH = struct {
|
||||||
|
Domain string `ini:"SSH_DOMAIN"`
|
||||||
|
Port int `ini:"SSH_PORT"`
|
||||||
|
User string `ini:"SSH_USER"`
|
||||||
|
- ListenHost string `ini:"SSH_LISTEN_HOST"`
|
||||||
|
+ ListenHost []string `ini:"SSH_LISTEN_HOST"`
|
||||||
|
ListenPort int `ini:"SSH_LISTEN_PORT"`
|
||||||
|
RootPath string `ini:"SSH_ROOT_PATH"`
|
||||||
|
ServerCiphers []string `ini:"SSH_SERVER_CIPHERS"`
|
||||||
|
@@ -54,6 +54,7 @@ var SSH = struct {
|
||||||
|
Disabled: false,
|
||||||
|
StartBuiltinServer: false,
|
||||||
|
Domain: "",
|
||||||
|
+ ListenHost: []string{"0.0.0.0"},
|
||||||
|
Port: 22,
|
||||||
|
ServerCiphers: []string{"chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com"},
|
||||||
|
ServerKeyExchanges: []string{"curve25519-sha256", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1"},
|
||||||
|
diff --git a/modules/ssh/init.go b/modules/ssh/init.go
|
||||||
|
index 21d4f89936..3800762632 100644
|
||||||
|
--- a/modules/ssh/init.go
|
||||||
|
+++ b/modules/ssh/init.go
|
||||||
|
@@ -11,6 +11,7 @@ import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
+ "code.gitea.io/gitea/modules/graceful"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
)
|
||||||
|
@@ -22,12 +23,23 @@ func Init() error {
|
||||||
|
}
|
||||||
|
|
||||||
|
if setting.SSH.StartBuiltinServer {
|
||||||
|
- Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs)
|
||||||
|
- log.Info("SSH server started on %s. Cipher list (%v), key exchange algorithms (%v), MACs (%v)",
|
||||||
|
- net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)),
|
||||||
|
- setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs,
|
||||||
|
- )
|
||||||
|
+ if len(setting.SSH.ListenHost) > 1 {
|
||||||
|
+ graceful.GetManager().IncreaseListenerCountBy(len(setting.SSH.ListenHost) - 1)
|
||||||
|
+ }
|
||||||
|
+ for _, listenHost := range setting.SSH.ListenHost {
|
||||||
|
+ var addr string
|
||||||
|
+ if _, _, err := net.SplitHostPort(listenHost); err == nil {
|
||||||
|
+ addr = listenHost
|
||||||
|
+ } else {
|
||||||
|
+ addr = net.JoinHostPort(listenHost, strconv.Itoa(setting.SSH.ListenPort))
|
||||||
|
+ }
|
||||||
|
+ Listen(addr, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs)
|
||||||
|
+ log.Info("SSH server started on %s. Cipher list (%v), key exchange algorithms (%v), MACs (%v)",
|
||||||
|
+ addr, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs,
|
||||||
|
+ )
|
||||||
|
+ }
|
||||||
|
return nil
|
||||||
|
+
|
||||||
|
}
|
||||||
|
|
||||||
|
builtinUnused()
|
||||||
|
diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go
|
||||||
|
index a5af5c129b..ab2021cfbd 100644
|
||||||
|
--- a/modules/ssh/ssh.go
|
||||||
|
+++ b/modules/ssh/ssh.go
|
||||||
|
@@ -18,7 +18,6 @@ import (
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
- "strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
@@ -279,10 +278,10 @@ func sshConnectionFailed(conn net.Conn, err error) {
|
||||||
|
log.Warn("Failed authentication attempt from %s", conn.RemoteAddr())
|
||||||
|
}
|
||||||
|
|
||||||
|
-// Listen starts a SSH server listens on given port.
|
||||||
|
-func Listen(host string, port int, ciphers, keyExchanges, macs []string) {
|
||||||
|
+// Listen starts a SSH server listens on given addr (host, port combination).
|
||||||
|
+func Listen(addr string, ciphers, keyExchanges, macs []string) {
|
||||||
|
srv := ssh.Server{
|
||||||
|
- Addr: net.JoinHostPort(host, strconv.Itoa(port)),
|
||||||
|
+ Addr: addr,
|
||||||
|
PublicKeyHandler: publicKeyHandler,
|
||||||
|
Handler: sessionHandler,
|
||||||
|
ServerConfigCallback: func(ctx ssh.Context) *gossh.ServerConfig {
|
||||||
|
diff --git a/tests/integration/git_helper_for_declarative_test.go b/tests/integration/git_helper_for_declarative_test.go
|
||||||
|
index 1e99783096..a099d414c6 100644
|
||||||
|
--- a/tests/integration/git_helper_for_declarative_test.go
|
||||||
|
+++ b/tests/integration/git_helper_for_declarative_test.go
|
||||||
|
@@ -52,7 +52,7 @@ func createSSHUrl(gitPath string, u *url.URL) *url.URL {
|
||||||
|
u2 := *u
|
||||||
|
u2.Scheme = "ssh"
|
||||||
|
u2.User = url.User("git")
|
||||||
|
- u2.Host = net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort))
|
||||||
|
+ u2.Host = net.JoinHostPort(setting.SSH.ListenHost[0], strconv.Itoa(setting.SSH.ListenPort))
|
||||||
|
u2.Path = gitPath
|
||||||
|
return &u2
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
./apps/collabora.nix
|
./apps/collabora.nix
|
||||||
./apps/coturn.nix
|
./apps/coturn.nix
|
||||||
./apps/forgejo.nix
|
./apps/forgejo
|
||||||
./apps/keycloak.nix
|
./apps/keycloak.nix
|
||||||
./apps/mailman.nix
|
./apps/mailman.nix
|
||||||
./apps/mastodon.nix
|
./apps/mastodon.nix
|
||||||
|
|
|
@ -26,4 +26,15 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.openssh.listenAddresses = [
|
||||||
|
{
|
||||||
|
addr = "10.7.6.1";
|
||||||
|
port = 22;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
addr = "[fd00:fae:fae:fae:fae:1::]";
|
||||||
|
port = 22;
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue