diff --git a/Dockerfile b/Dockerfile index 6df5a28..e1e22c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,8 +4,10 @@ FROM golang:1.25.2-alpine AS builder WORKDIR /app COPY . . +# 使用构建参数传递编译时间 +ARG BUILD_DATE ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 -RUN go build -o dot main.go +RUN go build -a -ldflags "-X main.BuildDate=${BUILD_DATE} -extldflags '-static -lc'" # ---------- 运行阶段 ---------- FROM alpine:3.20 diff --git a/README.md b/README.md index 1a66777..d949a72 100644 --- a/README.md +++ b/README.md @@ -159,4 +159,3 @@ kdig @127.0.0.1 +tls-ca +tls-host=dot.local www.example.com **Email:** [aixiao@aixiao.me](mailto:aixiao@aixiao.me) **License:** MIT **Repository:** [git.aixiao.me/aixiao/dot](https://git.aixiao.me/aixiao/dot) - diff --git a/blacklist.txt b/blacklist.txt index e34a910..e69de29 100644 --- a/blacklist.txt +++ b/blacklist.txt @@ -1 +0,0 @@ -*.baidu.com diff --git a/build.sh b/build.sh index 955a88a..38fe72d 100644 --- a/build.sh +++ b/build.sh @@ -27,70 +27,83 @@ KEY_FILE="jinllpay.com.key" # ---------- 函数区 ---------- build() { - echo "🔨 Building Docker image: ${IMAGE_NAME}:${TAG} ..." - docker build -t "${IMAGE_NAME}:${TAG}" . - echo "✅ Build complete." + echo "🔨 Building Docker image: ${IMAGE_NAME}:${TAG} ..." + docker build --build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ + -t "${IMAGE_NAME}:${TAG}" . + + echo "✅ Build complete." } run() { - echo "🚀 Starting container ${CONTAINER_NAME}..." + echo "🚀 Starting container ${CONTAINER_NAME}..." - # 确保旧容器不冲突 - if docker ps -a --format '{{.Names}}' | grep -w "${CONTAINER_NAME}" >/dev/null 2>&1; then - echo "⚠️ Existing container found. Removing..." - docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true - fi + # 确保旧容器不冲突 + if docker ps -a --format '{{.Names}}' | grep -w "${CONTAINER_NAME}" >/dev/null 2>&1; then + echo "⚠️ Existing container found. Removing..." + docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true + fi - docker run -d \ - --name "${CONTAINER_NAME}" \ - --memory=256m \ - --memory-swap=384m \ - --memory-reservation=128m \ - -p ${PORT}:853 \ - -e CERT_FILE="/app/${CERT_FILE}" \ - -e KEY_FILE="/app/${KEY_FILE}" \ - -v "$(pwd)/${CERT_FILE}:/app/${CERT_FILE}:ro" \ - -v "$(pwd)/${KEY_FILE}:/app/${KEY_FILE}:ro" \ - "${IMAGE_NAME}:${TAG}" + docker run -d \ + --name "${CONTAINER_NAME}" \ + --memory=256m \ + --memory-swap=384m \ + --memory-reservation=128m \ + -p ${PORT}:853 \ + -e CERT_FILE="/app/${CERT_FILE}" \ + -e KEY_FILE="/app/${KEY_FILE}" \ + -v "$(pwd)/${CERT_FILE}:/app/${CERT_FILE}:ro" \ + -v "$(pwd)/${KEY_FILE}:/app/${KEY_FILE}:ro" \ + "${IMAGE_NAME}:${TAG}" - echo "✅ Container started on port ${PORT}." + echo "✅ Container started on port ${PORT}." } logs() { - echo "📜 Showing logs..." - docker logs -f "${CONTAINER_NAME}" + echo "📜 Showing logs..." + docker logs -f "${CONTAINER_NAME}" } stop() { - echo "🛑 Stopping container..." - docker stop "${CONTAINER_NAME}" >/dev/null 2>&1 || true - docker rm "${CONTAINER_NAME}" >/dev/null 2>&1 || true - echo "✅ Container stopped and removed." + echo "🛑 Stopping container..." + docker stop "${CONTAINER_NAME}" >/dev/null 2>&1 || true + docker rm "${CONTAINER_NAME}" >/dev/null 2>&1 || true + echo "✅ Container stopped and removed." } clean() { - stop - echo "🧹 Removing image ${IMAGE_NAME}:${TAG}..." - docker rmi "${IMAGE_NAME}:${TAG}" >/dev/null 2>&1 || true - echo "✅ Cleanup complete." + stop + echo "🧹 Removing image ${IMAGE_NAME}:${TAG}..." + docker rmi "${IMAGE_NAME}:${TAG}" >/dev/null 2>&1 || true + echo "✅ Cleanup complete." } rebuild() { - clean - build - run + clean + build + run +} + +bin() { + DATE=$(date "+%Y-%m-%dT%H:%M:%S") + a="'" + eval "CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -a -ldflags ${a}-X main.BuildDate=${DATE} -extldflags \"-static -lc\"${a}" + + if test -f dot; then + upx -9 dot + fi } # ---------- 主逻辑 ---------- case "$1" in - build) build ;; - run) run ;; - logs) logs ;; - stop) stop ;; - clean) clean ;; - rebuild) rebuild ;; - *) - echo "Usage: ./build.sh [build|run|logs|stop|clean|rebuild]" - exit 1 - ;; + bin) bin ;; + build) build ;; + run) run ;; + logs) logs ;; + stop) stop ;; + clean) clean ;; + rebuild) rebuild ;; + *) + echo "Usage: ./build.sh [build|run|logs|stop|clean|rebuild]" + exit 1 + ;; esac diff --git a/dot b/dot index 1c261b4..6e4be62 100644 Binary files a/dot and b/dot differ diff --git a/main.go b/main.go index d07e4c9..45c4334 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,8 @@ import ( lru "github.com/hashicorp/golang-lru/v2" ) +var BuildDate = "unknown" // 由编译时注入 + /****************************************************************** * 日志初始化 ******************************************************************/ @@ -571,6 +573,7 @@ func handleDNS( func main() { rand.Seed(time.Now().UnixNano()) + var help bool certFile := flag.String("cert", "server.crt", "TLS 证书文件路径") keyFile := flag.String("key", "server.key", "TLS 私钥文件路径") addr := flag.String("addr", ":853", "DoT 监听地址") @@ -585,8 +588,24 @@ func main() { blacklistFile := flag.String("blacklist-file", "", "黑名单文件路径(每行一个域名;支持 # 或 ; 注释;后缀匹配)") blacklistRcodeFlag := flag.String("blacklist-rcode", "REFUSED", "命中黑名单返回的 RCODE:REFUSED|NXDOMAIN|SERVFAIL") verbose := flag.Bool("v", false, "verbose 日志") + + flag.BoolVar(&help, "h", false, "") + flag.BoolVar(&help, "help", false, "帮助信息") + flag.Parse() + if help { + fmt.Printf( + "\t\tDNS-over-TLS (DoT)\n"+ + "\tVersion 0.1\n"+ + "\tE-mail: aixiao@aixiao.me\n"+ + "\tBuild Date: %s\n", BuildDate) + + flag.Usage() + fmt.Printf("\n") + os.Exit(0) + } + initLogger(*verbose) var err error