diff --git a/cmd/cgr-console/cgr-console.go b/cmd/cgr-console/cgr-console.go
index a7b7e3bb0..fa44b5f2b 100644
--- a/cmd/cgr-console/cgr-console.go
+++ b/cmd/cgr-console/cgr-console.go
@@ -19,11 +19,14 @@ along with this program. If not, see
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 ")
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
diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go
index e87f9de91..b8189a904 100644
--- a/cmd/cgr-engine/cgr-engine.go
+++ b/cmd/cgr-engine/cgr-engine.go
@@ -844,6 +844,7 @@ func startRpc(server *utils.Server, internalRaterChan,
cfg.HTTPUseBasicAuth,
cfg.HTTPAuthUsers,
)
+ go server.ServeTLS(cfg.RPCJSONListen)
}
func writePid() {
diff --git a/utils/server.go b/utils/server.go
index 6198a42b4..e1ad5d328 100644
--- a/utils/server.go
+++ b/utils/server.go
@@ -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(" 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(" New incoming connection: %v", conn.RemoteAddr()))
+ go rpc.ServeConn(conn)
+ }
+
+}