Compare commits

9 Commits

12 changed files with 143 additions and 97 deletions

View File

@@ -90,7 +90,7 @@ trok = {
inputs.trok.nixosModules.default
];
tux.services.trok = {
services.trok = {
enable = true;
host = "0.0.0.0";
port = 1337;

View File

@@ -16,18 +16,24 @@ var tcpCmd = &cobra.Command{
Short: "Start TCP proxy",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
port := args[0]
localPort := args[0]
serverAddr, err := cmd.Flags().GetString("server")
if err != nil {
panic(err)
}
client.Start(serverAddr, fmt.Sprintf(":%s", port))
remotePort, err := cmd.Flags().GetString("port")
if err != nil {
panic(err)
}
client.Start(serverAddr, fmt.Sprintf(":%s", localPort), remotePort)
},
}
func init() {
rootCmd.AddCommand(tcpCmd)
tcpCmd.Flags().StringP("server", "s", "trok.cloud:1337", "Remote server address")
tcpCmd.Flags().StringP("port", "p", "0", "port on the remote server")
}

57
flake.lock generated
View File

@@ -1,5 +1,23 @@
{
"nodes": {
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1788450739,
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1740547748,
@@ -16,9 +34,46 @@
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1788057806,
"narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs",
"treefmt-nix": "treefmt-nix"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1786901030,
"narHash": "sha256-WSFCsDSE5ffgD2MqzkM2CYjeFiKhRF/dJUN8uedb6YE=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "27b3b12a8e6375f28ebe122f07d230ca5459bbfa",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
}
},

View File

@@ -1,29 +1,43 @@
{
description = "Simple tunneler in Go that exposes local ports to the internet";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
description =
"Simple tunneler in Go that exposes local ports to the internet";
outputs = {
self,
nixpkgs,
}: let
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
forAllSystems = function: nixpkgs.lib.genAttrs systems (system: function nixpkgs.legacyPackages.${system});
in {
packages = forAllSystems (pkgs: rec {
default = trok;
trok = pkgs.callPackage ./default.nix {};
});
nixosModules.default = ./module.nix;
devShells = forAllSystems (pkgs: {
default = pkgs.callPackage ./shell.nix {};
});
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
imports = [ inputs.treefmt-nix.flakeModule ];
systems =
[ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
perSystem = { config, pkgs, ... }: {
treefmt = {
projectRootFile = "flake.nix";
programs = {
nixfmt.enable = true;
gofumpt.enable = true;
};
};
packages = rec {
default = tfolio;
tfolio = pkgs.callPackage ./nix/package.nix { };
};
devShells.default = pkgs.callPackage ./nix/shell.nix { };
};
flake.nixosModules.default = ./nix/module.nix;
};
}

View File

@@ -11,8 +11,8 @@ import (
"github.com/rs/zerolog/log"
)
func Start(serverAddr, localAddr string) {
trok, err := NewTrokClient(serverAddr, localAddr)
func Start(serverAddr, localAddr, remotePort string) {
trok, err := NewTrokClient(serverAddr, localAddr, remotePort)
if err != nil {
log.Fatal().Msgf("failed init trok %v", err)
}

View File

@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"net"
"os"
"strings"
"github.com/rs/zerolog/log"
@@ -18,15 +19,17 @@ type Trok struct {
controlClient *TCPClient
serverAddr string
localAddr string
remotePort string
}
func NewTrokClient(serverAddr, localAddr string) (*Trok, error) {
func NewTrokClient(serverAddr, localAddr, remotePort string) (*Trok, error) {
controlClient, err := NewTCPClient(serverAddr, "Controller")
return &Trok{
controlClient: controlClient,
serverAddr: serverAddr,
localAddr: localAddr,
remotePort: remotePort,
}, err
}
@@ -45,7 +48,7 @@ func (t *Trok) Stop() {
func (t *Trok) ControlConnHandler(conn net.Conn) {
p := lib.InitProtocolHandler(conn)
p.WriteMessage(&lib.Message{CMD: "HELO", ARG: "Trok"})
p.WriteMessage(&lib.Message{CMD: "HELO", ARG: t.remotePort})
for {
m, err := p.ReadMessage()
@@ -61,18 +64,21 @@ func (t *Trok) ControlConnHandler(conn net.Conn) {
switch m.CMD {
case "EHLO":
go t.hanldeCMDEHLO(m)
go t.handleCMDEHLO(m)
case "CNCT":
go t.handleCMDCNCT(m)
case "ERR":
go t.handleCMDERR(m, conn)
default:
log.Info().Msgf("invalid command")
}
}
}
func (t *Trok) hanldeCMDEHLO(m *lib.Message) {
func (t *Trok) handleCMDEHLO(m *lib.Message) {
parts := strings.Split(t.serverAddr, ":")
log.Info().Msgf("[CMD] %s [ARG] %s:%s", m.CMD, parts[0], m.ARG)
}
@@ -96,3 +102,9 @@ func (t *Trok) handleCMDCNCT(m *lib.Message) {
go io.Copy(upStream.conn, downStream.conn)
io.Copy(downStream.conn, upStream.conn)
}
func (t *Trok) handleCMDERR(m *lib.Message, conn net.Conn) {
log.Info().Msgf("[CMD] %s [ARG] %s", m.CMD, m.ARG)
conn.Close()
os.Exit(1)
}

View File

@@ -30,7 +30,7 @@ type Trok struct {
func (t *Trok) Init(addr string) error {
t.publicConns = make(map[string]Conn)
t.webServer = NewTrokWeb(":443")
t.webServer = NewTrokWeb(":1338")
err := t.controlServer.Init(addr, "Controller")
return err
}
@@ -79,9 +79,10 @@ func (t *Trok) handleCMDHELO(p *lib.ProtocolHandler, m *lib.Message) {
log.Info().Msgf("[CMD] %s [ARG] %s", m.CMD, m.ARG)
var s TCPServer
err := s.Init(":", "Handler")
err := s.Init(fmt.Sprintf(":%s", m.ARG), "Handler")
if err != nil {
log.Error().Msgf("error handling HELO cmd: %v", err)
p.WriteMessage(&lib.Message{CMD: "ERR", ARG: "ADDRESS_UNAVAILABLE"})
return
}

View File

@@ -1,14 +1,12 @@
package server
import (
"crypto/tls"
"net/http"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/filesystem"
"github.com/rs/zerolog/log"
"github.com/tuxdotrs/trok/internal/web"
"golang.org/x/crypto/acme/autocert"
)
type TrokWeb struct {
@@ -36,29 +34,7 @@ func (t *TrokWeb) Start() {
Browse: true,
}))
cfg := t.GetTLSCert()
ln, err := tls.Listen("tcp", t.addr, cfg)
if err != nil {
log.Panic().Msgf("unable to start trok webserver: %v", err)
}
t.app.Listener(ln)
}
func (t *TrokWeb) GetTLSCert() *tls.Config {
m := &autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("trok.cloud"),
Cache: autocert.DirCache("./certs"),
}
return &tls.Config{
GetCertificate: m.GetCertificate,
NextProtos: []string{
"http/1.1", "acme-tls/1",
},
}
log.Panic().Err(t.app.Listen(t.addr)).Msg("unable to start trok webserver")
}
func (t *TrokWeb) Stop() {

View File

@@ -1,13 +1,8 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.tux.services.trok;
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.services.trok;
in {
options.tux.services.trok = {
options.services.trok = {
enable = mkEnableOption "Enable trok";
host = mkOption {
@@ -38,19 +33,20 @@ in {
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [cfg.port];
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
systemd.services = {
trok = {
description = "trok server";
after = ["network.target"];
wantedBy = ["multi-user.target"];
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
User = "trok";
Group = "trok";
ExecStart = "${getExe pkgs.trok} server -a ${cfg.host}:${toString cfg.port}";
ExecStart =
"${getExe pkgs.trok} server -a ${cfg.host}:${toString cfg.port}";
Restart = "always";
LockPersonality = true;
@@ -73,7 +69,7 @@ in {
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = ["@system-service"];
SystemCallFilter = [ "@system-service" ];
UMask = "0077";
};
};
@@ -89,8 +85,6 @@ in {
};
};
users.groups = mkIf (cfg.group == "trok") {
${cfg.group} = {};
};
users.groups = mkIf (cfg.group == "trok") { ${cfg.group} = { }; };
};
}

View File

@@ -1,17 +1,14 @@
{
lib,
buildGoModule,
}:
{ lib, buildGoModule }:
buildGoModule {
pname = "trok";
version = "0.2.0";
src = ./.;
src = ../.;
vendorHash = "sha256-KwcLxkW3pbzujjc6JOZRwATlAA/qndf4FWpkJANv2z8=";
meta = {
license = lib.licenses.mit;
maintainers = with lib.maintainers; [tuxdotrs];
maintainers = with lib.maintainers; [ tuxdotrs ];
mainProgram = "trok";
};
}

4
nix/shell.nix Normal file
View File

@@ -0,0 +1,4 @@
{ callPackage, go, }:
let mainPkg = callPackage ./package.nix { };
in mainPkg.overrideAttrs
(oa: { nativeBuildInputs = [ go ] ++ (oa.nativeBuildInputs or [ ]); })

View File

@@ -1,13 +0,0 @@
{
callPackage,
go,
}: let
mainPkg = callPackage ./default.nix {};
in
mainPkg.overrideAttrs (oa: {
nativeBuildInputs =
[
go
]
++ (oa.nativeBuildInputs or []);
})