{"id":19065486,"url":"https://github.com/menci/tsukasa","last_synced_at":"2025-06-17T05:33:12.955Z","repository":{"id":254139473,"uuid":"845605160","full_name":"Menci/Tsukasa","owner":"Menci","description":"A flexible port forwarder among TCP, UNIX socket and (optionally) Tailscale, with PROXY protocol support, written in Golang.","archived":false,"fork":false,"pushed_at":"2024-09-24T17:39:01.000Z","size":33,"stargazers_count":13,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-18T15:17:34.462Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Menci.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-08-21T15:09:44.000Z","updated_at":"2024-11-26T11:17:01.000Z","dependencies_parsed_at":"2025-04-18T03:54:40.900Z","dependency_job_id":"cb94463d-4996-487b-b6d0-0a580c1aa133","html_url":"https://github.com/Menci/Tsukasa","commit_stats":null,"previous_names":["menci/tsukasa"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2FTsukasa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2FTsukasa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2FTsukasa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2FTsukasa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Menci","download_url":"https://codeload.github.com/Menci/Tsukasa/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251304159,"owners_count":21567824,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T00:50:26.416Z","updated_at":"2025-04-28T11:28:35.458Z","avatar_url":"https://github.com/Menci.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tsusaka\n\nTsusaka is a flexible port forwarder among:\n\n* TCP Ports\n* UNIX Sockets\n* Tailscale TCP Ports (without Tailscale daemon or TUN/TAP permission! This is made possible with [tsnet](https://tailscale.com/kb/1244/tsnet))\n  * Also supports SOCKS5/HTTP proxy feature of `tailscaled`.\n  * If you don't use Tailscale features, it won't initialize Tailscale components and just behaves like a local port forwarder.\n\nIt also supports passing the client IP with PROXY protocol (for listening on TCP or Tailscale TCP).\n\n\u003e The name Tsusaka comes from the character **Tenma Tsukasa** from the music visual novel game Project SEKAI. He is a member of the musical show unit \"Wonderlands x Showtime\". Tsukasa has bucketloads of confidence and loves to be the center of attention. A theater show he saw as a kid impressed him so much that he made it his ultimate goal to become the greatest star in the world.\n\n# Development\n\nSimply build the program with `go build` or build the Docker image with `docker build`.\n\n# Usage\n\nUse with command-line configuration:\n\n```bash\n./tsusaka --ts-hostname Tsusaka \\\n          --ts-authkey \"$TS_AUTHKEY\" \\\n          --ts-ephemeral false \\\n          --ts-state-dir /var/lib/tailscale \\\n          --ts-listen-socks5 localhost:1080 \\\n          --ts-listen-http localhost:8080 \\\n          --ts-verbose true \\\n          nginx,listen=tailscale://0.0.0.0:80,connect=tcp://127.0.0.1:8080,log-level=info,proxy-protocol \\\n          myapp,listen=unix:/var/run/myapp.sock,connect=tailscale://app-hosted-in-tailnet:8080\n```\n\nOr use with configuration file:\n\n```yaml\n# Tailscale configuration is not required and Tailsccale will not be loaded if no services with Tailscale defined.\ntailscale:\n  hostname: Tsusaka\n  # `null` to Use `TS_AUTHKEY` from environment or interactive login.\n  authKey: null\n  ephemeral: false\n  stateDir: /var/lib/tailscale\n  listen:\n    socks5: 1080\n    http: 8080\n  verbose: true\nservices:\n  nginx:\n    listen: tailscale://0.0.0.0:80 # Only \"0.0.0.0\" and \"::\" allowed in Tailscale listener.\n    connect: tcp://127.0.0.1:8080\n    logLevel: info # \"error\" / \"info\" / \"verbose\". By default \"info\".\n    proxyProtocol: true # Listening on UNIX socket doesn't support PROXY protocol.\n  myapp:\n    listen: unix:/var/run/myapp.sock\n    connect: tailscale://app-hosted-in-tailnet:8080\n```\n\nConfiguration file could be specified with command-line configuration options at the same time.\n\n```bash\n./tsusaka --conf tsusaka.yaml\n```\n\nYou can also completely omit Tailscale-related configuration and use Tsukasa as a simple port forward between TCP port and UNIX socket.\n\n# Docker\n\nTo use Tsukasa with Docker, it's recommended to start Tsusaka in the host network mode to ensure Tailscale's UDP hole punching to work (Docker's MASQUERADE routing is nearly blocking NAT traversal).\n\n```bash\ndocker run \\\n  --network=host \\\n  -e TS_AUTHKEY=\"$TS_AUTHKEY\" \\\n  -v ./tailscale-state:/var/lib/tailscale \\\n  ghcr.io/menci/tsusaka \\\n  --ts-hostname Tsusaka \\\n  --ts-state-dir /var/lib/tailscale \\\n  myapp,listen=tcp://0.0.0.0:80,connect=tailscale://app-hosted-in-tailnet:8080\n```\n\nIf you want to expose something in a container to your Tailnet, use UNIX socket and a shared volume. Here is an example with [Docker Compose](https://docs.docker.com/compose/). Note that if your application doesn't support listening on a UNIX socket, you can also start another instance of Tsukasa to work as a simple port forwarder from/to UNIX socket and TCP port in the virtual network.\n\n```yaml\nservices:\n  initialize:\n    image: busybox\n    command: |\n      # The initialize container empties the shared-sockets directory each time.\n      rm -rf /socket/*\n    volumes:\n      - shared-sockets:/socket\n  tsukasa:\n    image: ghcr.io/menci/tsukasa\n    network_mode: host\n    depends_on:\n      initialize:\n        condition: service_completed_successfully\n    volumes:\n      - tailscale-state:/var/lib/tailscale\n      - shared-sockets:/socket\n    environment:\n      TS_AUTHKEY: ${TAILSCALE_AUTHKEY}\n    command:\n      - app,listen=tailscale://0.0.0.0:80,connect=unix:/socket/app.sock\n  app:\n    image: # Here comes your app, which listens on /socket/app.sock\n    depends_on:\n      initialize:\n        condition: service_completed_successfully\n    volumes:\n      - shared-sockets:/socket\n    command: my_app --listen /socket/app.sock\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmenci%2Ftsukasa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmenci%2Ftsukasa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmenci%2Ftsukasa/lists"}