Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.certs
.local-volumes

bin
89 changes: 73 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,40 +1,97 @@

# binary build command args
BINARY ?= cli
BIN_OUT ?= bin/$BINARY
BINARY ?= dino
BIN_OUT ?= bin/$(BINARY)
ABS_BIN_PATH := $(shell pwd)/$(BIN_OUT)

CERT_OUT ?= .certs

# version control docker build args
GO_VERSION ?= "1.25.5"
ALPINE_VERSION ?= "3.23"

DINO_HOSTNAME ?= tunnel.dino.local

# fips at build time
# on : enable
# off : disable
FIPS_MODE ?= "on"

.PHONY: protos lint test cli server tunnel certs all

.PHONY: clean
clean:
@rm -rf .certs .local-volumes
@mkdir -p .certs .local-volumes .local-volumes/pgdata

certs:
@echo "Generating ECDSA P-256 certs for $(DINO_HOSTNAME)..." \
mkdir -p $(CERT_OUT) \
openssl req -x509 -nodes -days 365 \
-newkey ec:<(openssl ecparam -name prime256v1) \
-keyout $(CERT_OUT)/backend.key \
-out $(CERT_OUT)/backend.cert \
-sha384 \
-subj "/C=US/ST=State/L=City/O=Dev/CN=$(DINO_HOSTNAME)" \
chmod 0644 $(CERT_OUT)/backend.cert $(CERT_OUT)/backend.key

protos:
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
pb/tunnels/v1/tunnel_service.proto
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
pb/rtunnel/v1/rtunnel_service.proto
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
pb/routes/v1/route_service.proto
@protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
pb/tunnels/v1/tunnel_service.proto
@protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
pb/rtunnel/v1/rtunnel_service.proto
@protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
pb/routes/v1/route_service.proto

lint:
@golangci-lint run ./...

test:
@go test -v ./...
@go test ./...

.PHONY: ci
ci: protos lint test

alias: cli
@echo "Configuring alias for $(BINARY)..."
@ALIAS_CMD="alias dino='$(ABS_BIN_PATH)'"; \
if [ -f "$$HOME/.zshrc" ]; then \
CONF="$$HOME/.zshrc"; \
elif [ -f "$$HOME/.bashrc" ]; then \
CONF="$$HOME/.bashrc"; \
else \
echo "No config file found"; exit 1; \
fi; \
if grep -q "alias dino=" "$$CONF"; then \
echo "Alias already exists in $$CONF. Skipping."; \
else \
echo "$$ALIAS_CMD" >> "$$CONF"; \
echo "Added alias to $$CONF. Run 'source $$CONF' to activate."; \
fi

unalias:
@if [ -f "$$HOME/.zshrc" ]; then sed -i '/alias dino=/d' ~/.zshrc; fi
@if [ -f "$$HOME/.bashrc" ]; then sed -i '/alias dino=/d' ~/.bashrc; fi
@echo "Removed dino alias from shell config files."

cli:
@GODEBUG=fips140=${FIPS_MODE} CGO_ENABLED=0 go build -o ./bin/dino ./cmd/cli
@CGO_ENABLED=0 go build -o $(BIN_OUT) ./cmd/cli

server:
docker build -t dino/server:latest \
--build-arg FIPS_ON=${FIPS_MODE} \
--build-arg GO_VERSION=${GO_VERSION} \
docker build -t dino/server:latest \
--build-arg FIPS_ON=${FIPS_MODE} \
--build-arg GO_VERSION=${GO_VERSION} \
--build-arg ALPINE_VERSION=${ALPINE_VERSION} \
-f docker/server.Dockerfile .

tunnel:
docker build -t dino/tunnel:latest \
--build-arg FIPS_ON=${FIPS_MODE} \
--build-arg GO_VERSION=${GO_VERSION} \
--build-arg ALPINE_VERSION=${ALPINE_VERSION} \
-f docker/tunnel.Dockerfile .

all: server tunnel
33 changes: 30 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,37 @@ Routing & Tunnel Management

## 🚀 Quick Start

1. **Clone & Launch**
```bash
# clone and enter repository
git clone https://github.com/structx/dino.git
cd dino
docker compose up -d

# create local volumes
mkdir -p .certs .local-volumes .local-volumes/pgdata

# set desired hostname for local tunnel
HOSTNAME="tunnel.dino.local"

# generate certs for local tunnel
openssl req -x509 -nodes -days 365 \
-newkey ec:<(openssl ecparam -name prime256v1) \
-keyout ./backend.key \
-out ./backend.cert \
-sha384 \
-subj "/C=US/ST=State/L=City/O=DinoDev/CN=$HOSTNAME"

# update local hosts file (requires sudo)
echo "127.0.0.1 api.dino.local traefik.dino.local tunnel.dino.local whoami.dino.local" | sudo tee -a /etc/hosts

# dockerize local server and tunnel
docker build -t dino/server:latest \
-f docker/server.Dockerfile .
docker build -t dino/tunnel:latest \
-f docker/tunnel.Dockerfile .

# start tunnel infra snd servers
docker compose -f tunnel.compose.yaml up -d

# verify dino has started
docker logs dino
```
2. Verify: `docker logs dino`
5 changes: 4 additions & 1 deletion docker/tunnel.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

FROM golang:1.25.3-alpine3.22
ARG ALPINE_VERSION=3.23
ARG GO_VERSION=1.25.5

FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION}

WORKDIR /usr/src/app

Expand Down
21 changes: 21 additions & 0 deletions local.compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
version: '3.9'

services:

tunnel:
image: dino/tunnel:latest
container_name: reverse-tunnel
restart: 'unless-stopped'
environment:
- name=value
networks:
- tunnel-network
- local-network

whoami:
image: dino/whoami:latest
container_name: whoami
networks:
- local-network

2 changes: 0 additions & 2 deletions scripts/generate_certs.sh

This file was deleted.

8 changes: 4 additions & 4 deletions setup/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ type Proxy struct {
Host string `env:"HOST, default=127.0.0.1"`
Port string `env:"PORT, default=8080"`

ReadTimeout time.Duration `env:"READ_TIMEOUT, default=15"`
ReadHeaderTimeout time.Duration `env:"READ_HEADER_TIMEOUT, default=15"`
WriteTimeout time.Duration `env:"WRITE_TIMEOUT, default=15"`
IdleTimeout time.Duration `env:"IDLE_TIMEOUT, default=30"`
ReadTimeout time.Duration `env:"READ_TIMEOUT, default=15s"`
ReadHeaderTimeout time.Duration `env:"READ_HEADER_TIMEOUT, default=15s"`
WriteTimeout time.Duration `env:"WRITE_TIMEOUT, default=15s"`
IdleTimeout time.Duration `env:"IDLE_TIMEOUT, default=30s"`
}

// Server
Expand Down
28 changes: 7 additions & 21 deletions docker-compose.yaml → tunnel.compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ services:
container_name: traefik-ingress
restart: 'unless-stopped'
depends_on:
- server
- dino
security_opt:
- no-new-privileges:true
- label=type:container_runtime_t
Expand Down Expand Up @@ -89,30 +89,16 @@ services:
- proxy
- dino-private-network
volumes:
- ${PWD}/certs/backend.cert:/etc/ssl/live/server.crt:z
- ${PWD}/certs/backend.key:/etc/ssl/live/server.key:z
- ${PWD}/.certs/backend.cert:/etc/ssl/live/server.crt:z
- ${PWD}/.certs/backend.key:/etc/ssl/live/server.key:z
ports:
- 50051
- 4242/udp

# tunnel:
# image: dino/tunnel:latest
# container_name: reverse-tunnel
# restart: 'unless-stopped'
# environment:
# - name=value
# networks:
# - tunnel-network
# - local-network

# whoami:
# image: dino/whoami:latest
# container_name: whoami
# networks:
# - local-network

networks:
proxy: # ingress network
external: true
name: dino-proxy
driver: bridge
dino-private-network: # private remote network
external: true
name: dino-private
internal: true