pupy/services/proxy/generate.go

231 lines
5.2 KiB
Go

package main
import (
"net"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"os"
"time"
log "github.com/sirupsen/logrus"
)
func GetOutboundIPv4() string {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP.String()
}
func GetOutboundIPv6() string {
conn, err := net.Dial("udp", "[2001:4860:4860::8888]:80")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP.String()
}
func CheckExternalBindHostIP() bool {
host := ExternalBindHost
if string(host[0]) == "[" {
host = ExternalBindHost[1 : len(ExternalBindHost)-1]
}
ifaces, err := net.Interfaces()
if err != nil {
return false
}
for _, i := range ifaces {
addrs, err := i.Addrs()
if err != nil {
continue
}
// handle err
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
// process IP address
if ip.String() == host {
return true
}
}
}
return false
}
func getCN() string {
switch {
case ProxyHostname != "":
return ProxyHostname
case CheckExternalBindHostIP():
return ExternalBindHost
default:
return GetOutboundIPv4()
}
}
func generateKeys() {
ca := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
Organization: []string{"Pupy CA"},
Country: []string{"ZZ"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageServerAuth,
},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
}
curve := elliptic.P384()
privCA, _ := ecdsa.GenerateKey(curve, rand.Reader)
pubCA := &privCA.PublicKey
ca_b, err := x509.CreateCertificate(rand.Reader, ca, ca, pubCA, privCA)
if err != nil {
log.Fatalln("create ca failed", err)
}
caSigned, _ := x509.ParseCertificate(ca_b)
certOut, err := os.Create(ListenerCA)
if err != nil {
log.Fatalln("Couldn't save CA certificate:", err)
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: ca_b})
certOut.Close()
log.Info("CA certificate saved to ", ListenerCA)
keyOut, err := os.OpenFile(ListenerCAKey, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Fatalln("Coulnd't save CA key:", err)
}
pk_b, _ := x509.MarshalECPrivateKey(privCA)
pem.Encode(keyOut, &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: pk_b,
})
keyOut.Close()
log.Info("CA key saved to ", ListenerCA)
proxyCert := &x509.Certificate{
SerialNumber: big.NewInt(1658),
Subject: pkix.Name{
Organization: []string{"Pupy"},
Country: []string{"ZZ"},
CommonName: getCN(),
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
SubjectKeyId: []byte{1},
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature,
}
proxyPriv, _ := ecdsa.GenerateKey(curve, rand.Reader)
proxyPub := &proxyPriv.PublicKey
proxyCert_b, err := x509.CreateCertificate(rand.Reader, proxyCert, caSigned, proxyPub, privCA)
if err != nil {
log.Fatalln("Couldn't generate server cert:", err)
}
certOut, err = os.Create(ListenerCert)
if err != nil {
log.Fatalln("Couldn't save proxy certificate:", err)
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: proxyCert_b})
certOut.Close()
log.Info("Proxy certificate saved to ", ListenerCert)
keyOut, err = os.OpenFile(ListenerKey, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Fatalln("Coulnd't save proxy key:", err)
}
proxyPriv_b, _ := x509.MarshalECPrivateKey(proxyPriv)
pem.Encode(keyOut, &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: proxyPriv_b,
})
keyOut.Close()
log.Info("Proxy key saved to ", ListenerKey)
clientCert := &x509.Certificate{
SerialNumber: big.NewInt(1658),
Subject: pkix.Name{
Organization: []string{"Pupy"},
Country: []string{"ZZ"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
SubjectKeyId: []byte{2},
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
KeyUsage: x509.KeyUsageDigitalSignature,
}
clientPriv, _ := ecdsa.GenerateKey(curve, rand.Reader)
clientPub := &clientPriv.PublicKey
clientCert_b, err := x509.CreateCertificate(rand.Reader, clientCert, caSigned, clientPub, privCA)
if err != nil {
log.Fatalln("Couldn't generate client cert:", err)
}
certOut, err = os.Create(ClientCert)
if err != nil {
log.Fatalln("Couldn't save client certificate:", err)
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: clientCert_b})
certOut.Close()
log.Info("Client cert saved to ", ClientCert)
keyOut, err = os.OpenFile(ClientKey, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Fatalln("Coulnd't save client key:", err)
}
clientPriv_b, _ := x509.MarshalECPrivateKey(clientPriv)
pem.Encode(keyOut, &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: clientPriv_b,
})
keyOut.Close()
log.Info("Client key saved to ", ClientKey)
}