mirror of
https://github.com/tuxdotrs/trok.git
synced 2026-09-19 23:19:03 +05:30
Compare commits
9 Commits
v0.0.3
...
adf7c84269
| Author | SHA1 | Date | |
|---|---|---|---|
|
adf7c84269
|
|||
|
a86a290e88
|
|||
|
6c13858d46
|
|||
|
ad3792139d
|
|||
|
c1ba1e55d0
|
|||
|
a616409ee0
|
|||
|
3cceda5835
|
|||
|
e451f17df0
|
|||
|
f586506180
|
@@ -90,7 +90,7 @@ trok = {
|
|||||||
inputs.trok.nixosModules.default
|
inputs.trok.nixosModules.default
|
||||||
];
|
];
|
||||||
|
|
||||||
tux.services.trok = {
|
services.trok = {
|
||||||
enable = true;
|
enable = true;
|
||||||
host = "0.0.0.0";
|
host = "0.0.0.0";
|
||||||
port = 1337;
|
port = 1337;
|
||||||
|
|||||||
10
cmd/tcp.go
10
cmd/tcp.go
@@ -16,18 +16,24 @@ var tcpCmd = &cobra.Command{
|
|||||||
Short: "Start TCP proxy",
|
Short: "Start TCP proxy",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
port := args[0]
|
localPort := args[0]
|
||||||
|
|
||||||
serverAddr, err := cmd.Flags().GetString("server")
|
serverAddr, err := cmd.Flags().GetString("server")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
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() {
|
func init() {
|
||||||
rootCmd.AddCommand(tcpCmd)
|
rootCmd.AddCommand(tcpCmd)
|
||||||
tcpCmd.Flags().StringP("server", "s", "trok.cloud:1337", "Remote server address")
|
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
57
flake.lock
generated
@@ -1,5 +1,23 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"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": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1740547748,
|
"lastModified": 1740547748,
|
||||||
@@ -16,9 +34,46 @@
|
|||||||
"type": "github"
|
"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": {
|
"root": {
|
||||||
"inputs": {
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
62
flake.nix
62
flake.nix
@@ -1,29 +1,43 @@
|
|||||||
{
|
{
|
||||||
description = "Simple tunneler in Go that exposes local ports to the internet";
|
description =
|
||||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
"Simple tunneler in Go that exposes local ports to the internet";
|
||||||
|
|
||||||
outputs = {
|
inputs = {
|
||||||
self,
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
nixpkgs,
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
}: let
|
|
||||||
systems = [
|
|
||||||
"x86_64-linux"
|
|
||||||
"aarch64-linux"
|
|
||||||
"x86_64-darwin"
|
|
||||||
"aarch64-darwin"
|
|
||||||
];
|
|
||||||
|
|
||||||
forAllSystems = function: nixpkgs.lib.genAttrs systems (system: function nixpkgs.legacyPackages.${system});
|
treefmt-nix = {
|
||||||
in {
|
url = "github:numtide/treefmt-nix";
|
||||||
packages = forAllSystems (pkgs: rec {
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
default = trok;
|
|
||||||
trok = pkgs.callPackage ./default.nix {};
|
|
||||||
});
|
|
||||||
|
|
||||||
nixosModules.default = ./module.nix;
|
|
||||||
|
|
||||||
devShells = forAllSystems (pkgs: {
|
|
||||||
default = pkgs.callPackage ./shell.nix {};
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Start(serverAddr, localAddr string) {
|
func Start(serverAddr, localAddr, remotePort string) {
|
||||||
trok, err := NewTrokClient(serverAddr, localAddr)
|
trok, err := NewTrokClient(serverAddr, localAddr, remotePort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Msgf("failed init trok %v", err)
|
log.Fatal().Msgf("failed init trok %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@@ -18,15 +19,17 @@ type Trok struct {
|
|||||||
controlClient *TCPClient
|
controlClient *TCPClient
|
||||||
serverAddr string
|
serverAddr string
|
||||||
localAddr 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")
|
controlClient, err := NewTCPClient(serverAddr, "Controller")
|
||||||
|
|
||||||
return &Trok{
|
return &Trok{
|
||||||
controlClient: controlClient,
|
controlClient: controlClient,
|
||||||
serverAddr: serverAddr,
|
serverAddr: serverAddr,
|
||||||
localAddr: localAddr,
|
localAddr: localAddr,
|
||||||
|
remotePort: remotePort,
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +48,7 @@ func (t *Trok) Stop() {
|
|||||||
func (t *Trok) ControlConnHandler(conn net.Conn) {
|
func (t *Trok) ControlConnHandler(conn net.Conn) {
|
||||||
p := lib.InitProtocolHandler(conn)
|
p := lib.InitProtocolHandler(conn)
|
||||||
|
|
||||||
p.WriteMessage(&lib.Message{CMD: "HELO", ARG: "Trok"})
|
p.WriteMessage(&lib.Message{CMD: "HELO", ARG: t.remotePort})
|
||||||
|
|
||||||
for {
|
for {
|
||||||
m, err := p.ReadMessage()
|
m, err := p.ReadMessage()
|
||||||
@@ -61,18 +64,21 @@ func (t *Trok) ControlConnHandler(conn net.Conn) {
|
|||||||
switch m.CMD {
|
switch m.CMD {
|
||||||
|
|
||||||
case "EHLO":
|
case "EHLO":
|
||||||
go t.hanldeCMDEHLO(m)
|
go t.handleCMDEHLO(m)
|
||||||
|
|
||||||
case "CNCT":
|
case "CNCT":
|
||||||
go t.handleCMDCNCT(m)
|
go t.handleCMDCNCT(m)
|
||||||
|
|
||||||
|
case "ERR":
|
||||||
|
go t.handleCMDERR(m, conn)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Info().Msgf("invalid command")
|
log.Info().Msgf("invalid command")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trok) hanldeCMDEHLO(m *lib.Message) {
|
func (t *Trok) handleCMDEHLO(m *lib.Message) {
|
||||||
parts := strings.Split(t.serverAddr, ":")
|
parts := strings.Split(t.serverAddr, ":")
|
||||||
log.Info().Msgf("[CMD] %s [ARG] %s:%s", m.CMD, parts[0], m.ARG)
|
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)
|
go io.Copy(upStream.conn, downStream.conn)
|
||||||
io.Copy(downStream.conn, upStream.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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type Trok struct {
|
|||||||
|
|
||||||
func (t *Trok) Init(addr string) error {
|
func (t *Trok) Init(addr string) error {
|
||||||
t.publicConns = make(map[string]Conn)
|
t.publicConns = make(map[string]Conn)
|
||||||
t.webServer = NewTrokWeb(":443")
|
t.webServer = NewTrokWeb(":1338")
|
||||||
err := t.controlServer.Init(addr, "Controller")
|
err := t.controlServer.Init(addr, "Controller")
|
||||||
return err
|
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)
|
log.Info().Msgf("[CMD] %s [ARG] %s", m.CMD, m.ARG)
|
||||||
|
|
||||||
var s TCPServer
|
var s TCPServer
|
||||||
err := s.Init(":", "Handler")
|
err := s.Init(fmt.Sprintf(":%s", m.ARG), "Handler")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msgf("error handling HELO cmd: %v", err)
|
log.Error().Msgf("error handling HELO cmd: %v", err)
|
||||||
|
p.WriteMessage(&lib.Message{CMD: "ERR", ARG: "ADDRESS_UNAVAILABLE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/tuxdotrs/trok/internal/web"
|
"github.com/tuxdotrs/trok/internal/web"
|
||||||
"golang.org/x/crypto/acme/autocert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TrokWeb struct {
|
type TrokWeb struct {
|
||||||
@@ -36,29 +34,7 @@ func (t *TrokWeb) Start() {
|
|||||||
Browse: true,
|
Browse: true,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
cfg := t.GetTLSCert()
|
log.Panic().Err(t.app.Listen(t.addr)).Msg("unable to start trok webserver")
|
||||||
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TrokWeb) Stop() {
|
func (t *TrokWeb) Stop() {
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
{
|
{ config, lib, pkgs, ... }:
|
||||||
config,
|
with lib;
|
||||||
lib,
|
let cfg = config.services.trok;
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib; let
|
|
||||||
cfg = config.tux.services.trok;
|
|
||||||
in {
|
in {
|
||||||
options.tux.services.trok = {
|
options.services.trok = {
|
||||||
enable = mkEnableOption "Enable trok";
|
enable = mkEnableOption "Enable trok";
|
||||||
|
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
@@ -38,19 +33,20 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [cfg.port];
|
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||||
|
|
||||||
systemd.services = {
|
systemd.services = {
|
||||||
trok = {
|
trok = {
|
||||||
description = "trok server";
|
description = "trok server";
|
||||||
after = ["network.target"];
|
after = [ "network.target" ];
|
||||||
wantedBy = ["multi-user.target"];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
User = "trok";
|
User = "trok";
|
||||||
Group = "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";
|
Restart = "always";
|
||||||
|
|
||||||
LockPersonality = true;
|
LockPersonality = true;
|
||||||
@@ -73,7 +69,7 @@ in {
|
|||||||
RestrictRealtime = true;
|
RestrictRealtime = true;
|
||||||
RestrictSUIDSGID = true;
|
RestrictSUIDSGID = true;
|
||||||
SystemCallArchitectures = "native";
|
SystemCallArchitectures = "native";
|
||||||
SystemCallFilter = ["@system-service"];
|
SystemCallFilter = [ "@system-service" ];
|
||||||
UMask = "0077";
|
UMask = "0077";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -89,8 +85,6 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups = mkIf (cfg.group == "trok") {
|
users.groups = mkIf (cfg.group == "trok") { ${cfg.group} = { }; };
|
||||||
${cfg.group} = {};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,14 @@
|
|||||||
{
|
{ lib, buildGoModule }:
|
||||||
lib,
|
|
||||||
buildGoModule,
|
|
||||||
}:
|
|
||||||
buildGoModule {
|
buildGoModule {
|
||||||
pname = "trok";
|
pname = "trok";
|
||||||
version = "0.2.0";
|
version = "0.2.0";
|
||||||
|
|
||||||
src = ./.;
|
src = ../.;
|
||||||
vendorHash = "sha256-KwcLxkW3pbzujjc6JOZRwATlAA/qndf4FWpkJANv2z8=";
|
vendorHash = "sha256-KwcLxkW3pbzujjc6JOZRwATlAA/qndf4FWpkJANv2z8=";
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
license = lib.licenses.mit;
|
license = lib.licenses.mit;
|
||||||
maintainers = with lib.maintainers; [tuxdotrs];
|
maintainers = with lib.maintainers; [ tuxdotrs ];
|
||||||
mainProgram = "trok";
|
mainProgram = "trok";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
4
nix/shell.nix
Normal file
4
nix/shell.nix
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{ callPackage, go, }:
|
||||||
|
let mainPkg = callPackage ./package.nix { };
|
||||||
|
in mainPkg.overrideAttrs
|
||||||
|
(oa: { nativeBuildInputs = [ go ] ++ (oa.nativeBuildInputs or [ ]); })
|
||||||
Reference in New Issue
Block a user