Added SOCKS5 support

This commit is contained in:
2026-05-21 22:40:31 +08:00
parent 74a7eb3828
commit f1597a6d57
3 changed files with 106 additions and 18 deletions
@@ -23,7 +23,7 @@ spec:
serviceAccountName: {{ include "freedns-webhook.fullname" . }} serviceAccountName: {{ include "freedns-webhook.fullname" . }}
containers: containers:
- name: {{ .Chart.Name }} - name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" image: "{{ .Values.image.repository }}{{- if .Values.image.digest }}@{{ .Values.image.digest }}{{- else }}:{{ .Values.image.tag }}{{- end }}"
imagePullPolicy: {{ .Values.image.pullPolicy }} imagePullPolicy: {{ .Values.image.pullPolicy }}
args: args:
- --v=2 - --v=2
+73 -17
View File
@@ -1,16 +1,21 @@
package freedns package freedns
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io"
"log"
"net"
"net/http" "net/http"
"net/url" "net/url"
"os"
"strconv" "strconv"
"strings" "strings"
logf "github.com/cert-manager/cert-manager/pkg/logs" logf "github.com/cert-manager/cert-manager/pkg/logs"
"golang.org/x/net/html" "golang.org/x/net/html"
"golang.org/x/net/proxy"
) )
type FreeDNSOperations interface { type FreeDNSOperations interface {
@@ -27,6 +32,10 @@ type FreeDNS struct {
LoggedOut bool LoggedOut bool
} }
type contextDialer interface {
DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
const URI_LOGIN = "https://freedns.afraid.org/zc.php?step=2" const URI_LOGIN = "https://freedns.afraid.org/zc.php?step=2"
const URI_DOMAIN = "https://freedns.afraid.org/domain/" const URI_DOMAIN = "https://freedns.afraid.org/domain/"
const URI_ADD_RECORD = "https://freedns.afraid.org/subdomain/save.php?step=2" const URI_ADD_RECORD = "https://freedns.afraid.org/subdomain/save.php?step=2"
@@ -41,43 +50,89 @@ func GetDomainFromZone(Zone string) string {
return strings.Join(_segs, ".") return strings.Join(_segs, ".")
} }
func _HttpRequest(method string, url string, PostData url.Values, ExCookie *http.Cookie) (*http.Response, string, error) { func newHTTPClient() (*http.Client, error) {
client := http.Client{ transport := http.DefaultTransport.(*http.Transport).Clone()
socksAddr := os.Getenv("SOCKS5_PROXY")
if socksAddr != "" {
log.Printf("using SOCKS5 proxy from SOCKS5_PROXY: %s", redactProxyAddr(socksAddr))
dialer, err := proxy.SOCKS5("tcp", socksAddr, nil, proxy.Direct)
if err != nil {
return nil, err
}
ctxDialer, ok := dialer.(interface {
DialContext(ctx context.Context, network, address string) (net.Conn, error)
})
if !ok {
return nil, fmt.Errorf("SOCKS5 dialer does not support DialContext")
}
transport.Proxy = nil
transport.DialContext = ctxDialer.DialContext
} else {
transport.Proxy = http.ProxyFromEnvironment
}
return &http.Client{
Transport: transport,
CheckRedirect: func(req *http.Request, via []*http.Request) error { CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse return http.ErrUseLastResponse
}, },
}, nil
}
func redactProxyAddr(addr string) string {
u, err := url.Parse(addr)
if err == nil && u.User != nil {
u.User = url.UserPassword("xxxxx", "xxxxx")
return u.String()
} }
var req *http.Request return addr
var err error }
if method == "GET" { func _HttpRequest(method string, reqURL string, postData url.Values, exCookie *http.Cookie) (*http.Response, string, error) {
req, err = http.NewRequest(method, url, nil) client, err := newHTTPClient()
} else if method == "POST" { if err != nil {
req, err = http.NewRequest(method, url, strings.NewReader(PostData.Encode())) return nil, "", err
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
} else {
return nil, "", errors.New("Method + \"" + method + "\" is not supported")
} }
var body io.Reader
switch method {
case http.MethodGet:
body = nil
case http.MethodPost:
body = strings.NewReader(postData.Encode())
default:
return nil, "", fmt.Errorf("method %q is not supported", method)
}
req, err := http.NewRequest(method, reqURL, body)
if err != nil { if err != nil {
return nil, "", err return nil, "", err
} }
req.Header.Set("User-Agent", "github.com/tgckpg/cert-manager-webhook-freedns (2022.03.15)") req.Header.Set("User-Agent", "github.com/tgckpg/cert-manager-webhook-freedns (2022.03.15)")
if ExCookie != nil { if method == http.MethodPost {
req.AddCookie(ExCookie) req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
if exCookie != nil {
req.AddCookie(exCookie)
} }
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return resp, "", err return resp, "", err
} }
defer resp.Body.Close()
respData, err := ioutil.ReadAll(resp.Body) respData, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil { if err != nil {
return resp, "", err return resp, "", err
} }
@@ -97,6 +152,7 @@ func (dnsObj *FreeDNS) Login(Username string, Password string) error {
if err != nil { if err != nil {
return err return err
} }
fmt.Println(err)
if strings.Contains(respString, "Invalid UserID/Pass") { if strings.Contains(respString, "Invalid UserID/Pass") {
return errors.New("Invalid UserID/Pass") return errors.New("Invalid UserID/Pass")
+32
View File
@@ -0,0 +1,32 @@
IMAGE_NAME := penguinade/cert-manager-webhook-freedns
IMAGE_TAG := dev
BUILDX_BUILDER := container-builder
ensure-buildx:
@if ! docker buildx inspect $(BUILDX_BUILDER) >/dev/null 2>&1; then \
echo "Creating buildx builder $(BUILDX_BUILDER)..."; \
docker buildx create \
--name $(BUILDX_BUILDER) \
--driver docker-container \
--driver-opt network=host \
--bootstrap --use; \
else \
echo "Using existing buildx builder $(BUILDX_BUILDER)"; \
docker buildx use $(BUILDX_BUILDER); \
fi
build: ensure-buildx
docker buildx build \
--platform linux/amd64,linux/arm64 \
-f Dockerfile \
-t $(IMAGE_NAME):$(IMAGE_TAG) .
push: ensure-buildx
docker buildx build \
--platform linux/amd64,linux/arm64 \
-f Dockerfile \
-t $(IMAGE_NAME):$(IMAGE_TAG) \
--push .
.PHONY: push