Add TLS Authentification

This commit is contained in:
TeoV
2018-05-29 05:33:23 -04:00
committed by Dan Christian Bogos
parent 31a4b51b02
commit c0721295c9
3 changed files with 106 additions and 0 deletions

View File

@@ -19,11 +19,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package main
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net/rpc"
"os"
"sort"
"strings"
@@ -42,6 +45,7 @@ var (
server = flag.String("server", "127.0.0.1:2012", "server address host:port")
rpc_encoding = flag.String("rpc_encoding", "json", "RPC encoding used <gob|json>")
client *rpcclient.RpcClient
client2 *rpc.Client
)
func executeCommand(command string) {
@@ -109,6 +113,15 @@ func executeCommand(command string) {
result, _ := json.MarshalIndent(res, "", " ")
fmt.Println(string(result))
}
//TLS call
if rpcErr := client2.Call(cmd.RpcMethod(), param, res); rpcErr != nil {
fmt.Println("Error executing command: " + rpcErr.Error())
} else {
result, _ := json.MarshalIndent(res, "", " ")
fmt.Println(string(result))
}
//
} else {
fmt.Println(cmd.LocalExecute())
}
@@ -128,6 +141,32 @@ func main() {
log.Fatal("Could not connect to server " + *server)
}
//TLS connection
cert, err := tls.LoadX509KeyPair("/home/teo/go/src/github.com/TeoV/GoRPCServerClientOverTLS/client1.crt",
"/home/teo/go/src/github.com/TeoV/GoRPCServerClientOverTLS/client.key")
if err != nil {
log.Fatalf("Error: %s when load client keys", err)
}
if len(cert.Certificate) != 2 {
log.Fatal("client1.crt should have 2 concatenated certificates: client + CA")
}
ca, err := x509.ParseCertificate(cert.Certificate[1])
if err != nil {
log.Fatal(err)
}
certPool := x509.NewCertPool()
certPool.AddCert(ca)
config := tls.Config{
Certificates: []tls.Certificate{cert},
//InsecureSkipVerify: true,
RootCAs: certPool,
}
conn, err := tls.Dial("tcp", "localhost:2022", &config)
if err != nil {
log.Fatalf("Error: %s when dialing", err)
}
client2 = rpc.NewClient(conn)
//
if len(flag.Args()) != 0 {
executeCommand(strings.Join(flag.Args(), " "))
return

View File

@@ -844,6 +844,7 @@ func startRpc(server *utils.Server, internalRaterChan,
cfg.HTTPUseBasicAuth,
cfg.HTTPAuthUsers,
)
go server.ServeTLS(cfg.RPCJSONListen)
}
func writePid() {

View File

@@ -20,6 +20,9 @@ package utils
import (
"bytes"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"log"
@@ -275,3 +278,66 @@ func (r *rpcRequest) Call() io.Reader {
<-r.done
return r.rw
}
func (s *Server) ServeTLS(addr string) {
s.RLock()
enabled := s.rpcEnabled
s.RUnlock()
if !enabled {
return
}
cert, err := tls.LoadX509KeyPair("/home/teo/go/src/github.com/TeoV/GoRPCServerClientOverTLS/server1.crt",
"/home/teo/go/src/github.com/TeoV/GoRPCServerClientOverTLS/server.key")
if err != nil {
log.Fatalf("Error: %s when load server keys", err)
}
if len(cert.Certificate) != 2 {
log.Fatal("server1.crt should have 2 concatenated certificates: server + CA")
}
ca, err := x509.ParseCertificate(cert.Certificate[1])
if err != nil {
log.Fatal(err)
}
certPool := x509.NewCertPool()
certPool.AddCert(ca)
config := tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certPool,
}
config.Rand = rand.Reader
service := ":2022"
listener, err := tls.Listen("tcp", service, &config)
if err != nil {
log.Fatalf("Error: %s when listening", err)
}
Logger.Info(fmt.Sprintf("Starting CGRateS TLS server at <%s>.", service))
errCnt := 0
var lastErrorTime time.Time
for {
conn, err := listener.Accept()
defer conn.Close()
if err != nil {
Logger.Err(fmt.Sprintf("<CGRServer> TLS accept error: <%s>", err.Error()))
now := time.Now()
if now.Sub(lastErrorTime) > time.Duration(5*time.Second) {
errCnt = 0 // reset error count if last error was more than 5 seconds ago
}
lastErrorTime = time.Now()
errCnt += 1
if errCnt > 50 { // Too many errors in short interval, network buffer failure most probably
break
}
continue
}
//utils.Logger.Info(fmt.Sprintf("<CGRServer> New incoming connection: %v", conn.RemoteAddr()))
go rpc.ServeConn(conn)
}
}