提交 16e94432 编写于 作者: H hanxinke

atune:use tls authentication by default in rest and engine server

上级 e6f0a5eb
......@@ -13,6 +13,13 @@ ATUNEVERSION = $(VERSION)$(if $(SRCVERSION),($(SRCVERSION)))
GOLDFLAGS += -X gitee.com/openeuler/A-Tune/common/config.Version=$(ATUNEVERSION)
GOFLAGS = -ldflags "$(GOLDFLAGS)"
CERT_PATH=/etc/atuned
GRPC_CERT_PATH=$(CERT_PATH)/grpc_certs
REST_CERT_PATH=$(CERT_PATH)/rest_certs
ENGINE_CERT_PATH=$(CERT_PATH)/engine_certs
REST_IP_ADDR=localhost
ENGINE_IP_ADDR=localhost
all: modules atune-adm atuned db
atune-adm:
......@@ -27,11 +34,22 @@ modules:
clean:
rm -rf $(PKGPATH)/*
cleanall: clean
rm -rf $(DESTDIR)/etc/atuned/
rm -rf $(DESTDIR)$(PREFIX)/lib/atuned/
rm -rf $(DESTDIR)$(PREFIX)/share/atuned/
rm -rf $(DESTDIR)$(PREFIX)/$(LIBEXEC)/atuned/
rm -rf $(DESTDIR)/var/lib/atuned/
rm -rf $(DESTDIR)/var/run/atuned/
rm -rf $(DESTDIR)/var/atuned/
db:
sqlite3 database/atuned.db ".read database/init.sql"
install:
@echo "BEGIN INSTALL A-Tune"
install: libinstall restcerts enginecerts
libinstall:
@echo "BEGIN INSTALL A-Tune..."
mkdir -p $(BINDIR)
mkdir -p $(SYSTEMDDIR)
rm -rf $(DESTDIR)/etc/atuned/
......@@ -81,3 +99,68 @@ rpm:
models:
rm -rf ${CURDIR}/analysis/models/*
cd ${CURDIR}/tools/ && python3 generate_models.py
grpccerts:
@echo "BEGIN GENERATE GRPC CERTS..."
mkdir -p $(GRPC_CERT_PATH)
openssl genrsa -out $(GRPC_CERT_PATH)/ca.key 2048
openssl req -new -x509 -days 3650 -subj "/CN=ca" -key $(GRPC_CERT_PATH)/ca.key -out $(GRPC_CERT_PATH)/ca.crt
@for name in server client; do \
openssl genrsa -out $(GRPC_CERT_PATH)/$$name.key 2048; \
openssl req -new -subj "/CN=$$name" -key $(GRPC_CERT_PATH)/$$name.key -out $(GRPC_CERT_PATH)/$$name.csr; \
openssl x509 -req -sha256 -CA $(GRPC_CERT_PATH)/ca.crt -CAkey $(GRPC_CERT_PATH)/ca.key -CAcreateserial -days 3650 \
-in $(GRPC_CERT_PATH)/$$name.csr -out $(GRPC_CERT_PATH)/$$name.crt; \
done
rm -rf $(GRPC_CERT_PATH)/*.srl $(GRPC_CERT_PATH)/*.csr
@echo "END GENERATE GRPC CERTS"
restcerts:
@echo "BEGIN GENERATE REST CERTS..."
mkdir -p $(REST_CERT_PATH)
openssl genrsa -out $(REST_CERT_PATH)/ca.key 2048
openssl req -new -x509 -days 3650 -subj "/CN=ca" -key $(REST_CERT_PATH)/ca.key -out $(REST_CERT_PATH)/ca.crt
openssl genrsa -out $(REST_CERT_PATH)/server.key 2048
@if test $(REST_IP_ADDR) == localhost; then \
openssl req -new -subj "/CN=localhost" -key $(REST_CERT_PATH)/server.key -out $(REST_CERT_PATH)/server.csr; \
openssl x509 -req -sha256 -CA $(REST_CERT_PATH)/ca.crt -CAkey $(REST_CERT_PATH)/ca.key -CAcreateserial -days 3650 \
-in $(REST_CERT_PATH)/server.csr -out $(REST_CERT_PATH)/server.crt; \
else \
openssl req -new -subj "/CN=$(REST_IP_ADDR)" -key $(REST_CERT_PATH)/server.key -out $(REST_CERT_PATH)/server.csr; \
echo "subjectAltName=IP:$(REST_IP_ADDR)" > $(REST_CERT_PATH)/extfile.cnf; \
openssl x509 -req -sha256 -CA $(REST_CERT_PATH)/ca.crt -CAkey $(REST_CERT_PATH)/ca.key -CAcreateserial -days 3650 \
-extfile $(REST_CERT_PATH)/extfile.cnf -in $(REST_CERT_PATH)/server.csr -out $(REST_CERT_PATH)/server.crt; \
fi
rm -rf $(REST_CERT_PATH)/*.srl $(REST_CERT_PATH)/*.csr $(REST_CERT_PATH)/extfile.cnf
@echo "END GENERATE REST CERTS"
enginecerts:
@echo "BEGIN GENERATE ENGINE CERTS..."
mkdir -p $(ENGINE_CERT_PATH)
@if test ! -f $(ENGINE_CERT_PATH)/ca.key; then \
openssl genrsa -out $(ENGINE_CERT_PATH)/ca.key 2048; \
openssl req -new -x509 -days 3650 -subj "/CN=ca" -key $(ENGINE_CERT_PATH)/ca.key -out $(ENGINE_CERT_PATH)/ca.crt; \
fi
@for name in server client; do \
openssl genrsa -out $(ENGINE_CERT_PATH)/$$name.key 2048; \
if test $(ENGINE_IP_ADDR) == localhost; then \
openssl req -new -subj "/CN=localhost" -key $(ENGINE_CERT_PATH)/$$name.key -out $(ENGINE_CERT_PATH)/$$name.csr; \
openssl x509 -req -sha256 -CA $(ENGINE_CERT_PATH)/ca.crt -CAkey $(ENGINE_CERT_PATH)/ca.key -CAcreateserial -days 3650 \
-in $(ENGINE_CERT_PATH)/$$name.csr -out $(ENGINE_CERT_PATH)/$$name.crt; \
else \
openssl req -new -subj "/CN=$(ENGINE_IP_ADDR)" -key $(ENGINE_CERT_PATH)/$$name.key -out $(ENGINE_CERT_PATH)/$$name.csr; \
echo "subjectAltName=IP:$(ENGINE_IP_ADDR)" > $(ENGINE_CERT_PATH)/extfile.cnf; \
openssl x509 -req -sha256 -CA $(ENGINE_CERT_PATH)/ca.crt -CAkey $(ENGINE_CERT_PATH)/ca.key -CAcreateserial -days 3650 \
-extfile $(ENGINE_CERT_PATH)/extfile.cnf -in $(ENGINE_CERT_PATH)/$$name.csr -out $(ENGINE_CERT_PATH)/$$name.crt; \
fi; \
done
rm -rf $(ENGINE_CERT_PATH)/*.srl $(ENGINE_CERT_PATH)/*.csr $(ENGINE_CERT_PATH)/extfile.cnf
@echo "END GENERATE ENGINE CERTS"
env:
@echo "BEGIN SET ENVIRONMENT VARIABLES..."
@echo "export ATUNED_TLS=yes" > $(GRPC_CERT_PATH)/env
@echo "export ATUNED_CACERT=$(GRPC_CERT_PATH)/ca.crt" >> $(CERT_PATH)/env
@echo "export ATUNED_CLIENTCERT=$(GRPC_CERT_PATH)/client.crt" >> $(CERT_PATH)/env
@echo "export ATUNED_CLIENTKEY=$(GRPC_CERT_PATH)/client.key" >> $(CERT_PATH)/env
@echo "export ATUNED_SERVERCN=server" >> $(CERT_PATH)/env
@echo "END SET ENVIRONMENT VARIABLES"
......@@ -65,10 +65,10 @@ def main(filename):
API.add_resource(collector.Collector, '/v1/collector', '/v1/collector')
API.add_resource(profile.Profile, '/v1/profile', '/v1/profile')
if config.has_option("server", "tls") and config.get("server", "tls") == "true":
cert_file = config.get("server", "tlshttpcertfile")
key_file = config.get("server", "tlshttpkeyfile")
ca_file = config.get("server", "tlshttpcacertfile")
if config.has_option("server", "rest_tls") and config.get("server", "rest_tls") == "true":
cert_file = config.get("server", "tlsrestservercertfile")
key_file = config.get("server", "tlsrestserverkeyfile")
ca_file = config.get("server", "tlsrestcacertfile")
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile=cert_file, keyfile=key_file)
context.load_verify_locations(ca_file)
......
......@@ -64,10 +64,10 @@ def main(filename):
API.add_resource(train.Training, '/v1/training', '/v1/training')
API.add_resource(transfer.Transfer, '/v1/transfer', '/transfer')
if config.has_option("server", "tls") and config.get("server", "tls") == "true":
cert_file = config.get("server", "tlshttpcertfile")
key_file = config.get("server", "tlshttpkeyfile")
ca_file = config.get("server", "tlshttpcacertfile")
if config.has_option("server", "engine_tls") and config.get("server", "engine_tls") == "true":
cert_file = config.get("server", "tlsengineservercertfile")
key_file = config.get("server", "tlsengineserverkeyfile")
ca_file = config.get("server", "tlsenginecacertfile")
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile=cert_file, keyfile=key_file)
context.load_verify_locations(ca_file)
......
......@@ -14,13 +14,16 @@
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"gitee.com/openeuler/A-Tune/common/config"
"gitee.com/openeuler/A-Tune/common/log"
"gitee.com/openeuler/A-Tune/common/registry"
SVC "gitee.com/openeuler/A-Tune/common/service"
"gitee.com/openeuler/A-Tune/common/sqlstore"
"gitee.com/openeuler/A-Tune/common/utils"
"fmt"
"io/ioutil"
"net"
"os"
......@@ -172,12 +175,28 @@ func runatuned(ctx *cli.Context) error {
}
var opts []grpc.ServerOption
if config.TLS {
if config.GrpcTLS {
log.Info("server tls enabled")
creds, err := credentials.NewServerTLSFromFile(config.TLSServerCertFile, config.TLSServerKeyFile)
pool := x509.NewCertPool()
caCrt, err := ioutil.ReadFile(config.TLSServerCaFile)
if err != nil {
return err
}
if ok := pool.AppendCertsFromPEM(caCrt); !ok {
return fmt.Errorf("failed to append ca certs in server")
}
certificate, err := tls.LoadX509KeyPair(config.TLSServerCertFile, config.TLSServerKeyFile)
if err != nil {
log.Fatalf("Failed to generate credentials %v", err)
return err
}
creds := credentials.NewTLS(&tls.Config{
Certificates: []tls.Certificate{certificate},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: pool,
})
opts = []grpc.ServerOption{grpc.Creds(creds)}
}
s := grpc.NewServer(opts...)
......
......@@ -14,8 +14,11 @@
package client
import (
"gitee.com/openeuler/A-Tune/common/config"
"crypto/tls"
"crypto/x509"
"fmt"
"gitee.com/openeuler/A-Tune/common/config"
"io/ioutil"
"net"
"os"
"time"
......@@ -153,13 +156,29 @@ func newClient(address string, opts ...Opt) (*Client, error) {
grpc.WithBackoffMaxDelay(3 * time.Second),
}
tls := os.Getenv(config.EnvTLS)
if tls == "yes" {
clicrt := os.Getenv(config.EnvCliCert)
creds, err := credentials.NewClientTLSFromFile(clicrt, "")
envTls := os.Getenv(config.EnvTLS)
if envTls == "yes" {
pool := x509.NewCertPool()
caCrt, err := ioutil.ReadFile(os.Getenv(config.EnvCaCert))
if err != nil {
return nil, err
}
if ok := pool.AppendCertsFromPEM(caCrt); !ok {
return nil, fmt.Errorf("failed to append ca certs in client")
}
certificate, err := tls.LoadX509KeyPair(os.Getenv(config.EnvClientCert),
os.Getenv(config.EnvClientKey))
if err != nil {
return nil, fmt.Errorf("failed to create TLS credentials %v", err)
return nil, err
}
creds := credentials.NewTLS(&tls.Config{
Certificates: []tls.Certificate{certificate},
ServerName: os.Getenv(config.EnvServerCN),
RootCAs: pool,
})
gopts = append(gopts, grpc.WithTransportCredentials(creds))
} else {
gopts = append(gopts, grpc.WithInsecure())
......
......@@ -28,10 +28,13 @@ var Version = "no version specified"
// application common config
const (
EnvAddr = "ATUNED_ADDR"
EnvPort = "ATUNED_PORT"
EnvTLS = "ATUNE_TLS"
EnvCliCert = "ATUNE_CLICERT"
EnvAddr = "ATUNED_ADDR"
EnvPort = "ATUNED_PORT"
EnvTLS = "ATUNED_TLS"
EnvCaCert = "ATUNED_CACERT"
EnvClientCert = "ATUNED_CLIENTCERT"
EnvClientKey = "ATUNED_CLIENTKEY"
EnvServerCN = "ATUNED_SERVERCN"
DefaultProtocol = "unix"
DefaultTgtAddr = "/var/run/atuned/atuned.sock"
......@@ -98,20 +101,28 @@ const (
// the grpc server config
var (
TransProtocol string
Address string
Connect string
Port string
LocalHost string
RestPort string
EngineHost string
EnginePort string
TLS bool
TLSServerCertFile string
TLSServerKeyFile string
TLSHTTPCertFile string
TLSHTTPKeyFile string
TLSHTTPCACertFile string
TransProtocol string
Address string
Connect string
Port string
LocalHost string
RestPort string
EngineHost string
EnginePort string
GrpcTLS bool
RestTLS bool
EngineTLS bool
TLSServerCaFile string
TLSServerCertFile string
TLSServerKeyFile string
TLSRestServerCertFile string
TLSRestServerKeyFile string
TLSRestCACertFile string
TLSEngineClientCertFile string
TLSEngineClientKeyFile string
TLSEngineServerCertFile string
TLSEngineServerKeyFile string
TLSEngineCACertFile string
)
// the tuning configs
......@@ -166,16 +177,36 @@ func (c *Cfg) Load() error {
utils.RestHost = LocalHost
utils.RestPort = RestPort
if section.HasKey("tls") {
TLS = section.Key("tls").MustBool(false)
if section.HasKey("grpc_tls") {
GrpcTLS = section.Key("grpc_tls").MustBool(false)
}
if TLS {
if section.HasKey("rest_tls") {
RestTLS = section.Key("rest_tls").MustBool(true)
}
if section.HasKey("engine_tls") {
EngineTLS = section.Key("engine_tls").MustBool(true)
}
if GrpcTLS {
TLSServerCaFile = section.Key("tlsservercafile").MustString("")
TLSServerCertFile = section.Key("tlsservercertfile").MustString("")
TLSServerKeyFile = section.Key("tlsserverkeyfile").MustString("")
TLSHTTPCertFile = section.Key("tlshttpcertfile").MustString("")
TLSHTTPKeyFile = section.Key("tlshttpkeyfile").MustString("")
TLSHTTPCACertFile = section.Key("tlshttpcacertfile").MustString("")
}
if RestTLS {
TLSRestServerCertFile = section.Key("tlsrestservercertfile").MustString("")
TLSRestServerKeyFile = section.Key("tlsrestserverkeyfile").MustString("")
TLSRestCACertFile = section.Key("tlsrestcacertfile").MustString("")
}
if EngineTLS {
TLSEngineClientCertFile = section.Key("tlsengineclientcertfile").MustString("")
TLSEngineClientKeyFile = section.Key("tlsengineclientkeyfile").MustString("")
TLSEngineServerCertFile = section.Key("tlsengineservercertfile").MustString("")
TLSEngineServerKeyFile = section.Key("tlsengineserverkeyfile").MustString("")
TLSEngineCACertFile = section.Key("tlsenginecacertfile").MustString("")
}
section = cfg.Section("system")
......@@ -222,13 +253,15 @@ func initLogging(cfg *ini.File) error {
// GetURL return the url
func GetURL(uri string) string {
protocol := Protocol
if TLS {
protocol = "https"
}
if IsEnginePort(uri) {
if EngineTLS {
protocol = "https"
}
return fmt.Sprintf("%s://%s:%s/%s/%s", protocol, EngineHost, EnginePort, APIVersion, uri)
}
if RestTLS {
protocol = "https"
}
url := fmt.Sprintf("%s://%s:%s/%s/%s", protocol, LocalHost, RestPort, APIVersion, uri)
return url
}
......
......@@ -37,17 +37,33 @@ func (c *httpClient) Do(req *http.Request) (*http.Response, error) {
return response, err
}
func newhttpClient() (*httpClient, error) {
// NewhttpClient create an http client
func NewhttpClient(url string) (*httpClient, error) {
var client *http.Client
if config.TLS {
segs := strings.Split(url, "/")
if len(segs) < 5 {
return nil, fmt.Errorf("url: %s is not corrent")
}
uri := segs[4]
if config.IsEnginePort(uri) && config.EngineTLS || !config.IsEnginePort(uri) && config.RestTLS {
pool := x509.NewCertPool()
caCrt, err := ioutil.ReadFile(config.TLSHTTPCACertFile)
caFile := config.TLSEngineCACertFile
if !config.IsEnginePort(uri) {
caFile = config.TLSRestCACertFile
}
caCrt, err := ioutil.ReadFile(caFile)
if err != nil {
return nil, err
}
pool.AppendCertsFromPEM(caCrt)
clientCrt, err := tls.LoadX509KeyPair(config.TLSHTTPCertFile, config.TLSHTTPKeyFile)
clientCertFile := config.TLSEngineClientCertFile
clientKeyFile := config.TLSEngineClientKeyFile
if !config.IsEnginePort(uri) {
clientCertFile = config.TLSRestServerCertFile
clientKeyFile = config.TLSRestServerKeyFile
}
clientCrt, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile)
if err != nil {
return nil, err
}
......@@ -96,7 +112,7 @@ func newRequest(method string, url string, body interface{}) (*http.Request, err
// Get method call the restfull GET method
func Get(url string, data interface{}) (*http.Response, error) {
restClient, err := newhttpClient()
restClient, err := NewhttpClient(url)
if err != nil {
return nil, err
}
......@@ -115,7 +131,7 @@ func Get(url string, data interface{}) (*http.Response, error) {
//Post method call the restfull POST method
func Post(url string, data interface{}) (*http.Response, error) {
restClient, err := newhttpClient()
restClient, err := NewhttpClient(url)
if err != nil {
return nil, err
}
......@@ -134,7 +150,7 @@ func Post(url string, data interface{}) (*http.Response, error) {
// Put method call the restfull PUT method
func Put(url string, data interface{}) (*http.Response, error) {
restClient, err := newhttpClient()
restClient, err := NewhttpClient(url)
if err != nil {
return nil, err
}
......@@ -153,7 +169,7 @@ func Put(url string, data interface{}) (*http.Response, error) {
// Delete method call the restfull DELETE method
func Delete(url string) (*http.Response, error) {
restClient, err := newhttpClient()
restClient, err := NewhttpClient(url)
if err != nil {
return nil, err
}
......
......@@ -266,10 +266,11 @@ func WaitForPyservice() error {
for {
select {
case <-ticker.C:
_, err := net.Dial("tcp", addr)
conn, err := net.Dial("tcp", addr)
if err != nil {
continue
}
conn.Close()
return nil
case <-timeout:
return fmt.Errorf("waiting for pyservice timeout")
......
......@@ -9,7 +9,7 @@ URL: https://gitee.com/openeuler/A-Tune
Source: openeuler-A-Tune-v%{version}.tar.gz
BuildRequires: rpm-build protobuf-compiler golang-bin python3-pytest procps-ng
BuildRequires: sqlite >= 3.24.0
BuildRequires: sqlite >= 3.24.0 openssl
Requires: systemd
Requires: atune-client
Requires: atune-db
......
......@@ -47,14 +47,28 @@ sample_num = 20
# interval for collecting data, default is 5s
interval = 5
# enable gRPC and http server authentication SSL/TLS
# enable gRPC authentication SSL/TLS
# default is false
# tls = true
# tlsservercertfile = /etc/atuned/server.pem
# tlsserverkeyfile = /etc/atuned/server.key
# tlshttpcertfile = /etc/atuned/http/server.pem
# tlshttpkeyfile = /etc/atuned/http/server.key
# tlshttpcacertfile = /etc/atuned/http/cacert.pem
# grpc_tls = false
# tlsservercafile = /etc/atuned/grpc_certs/ca.crt
# tlsservercertfile = /etc/atuned/grpc_certs/server.crt
# tlsserverkeyfile = /etc/atuned/grpc_certs/server.key
# enable rest server authentication SSL/TLS
# default is true
rest_tls = true
tlsrestcacertfile = /etc/atuned/rest_certs/ca.crt
tlsrestservercertfile = /etc/atuned/rest_certs/server.crt
tlsrestserverkeyfile = /etc/atuned/rest_certs/server.key
# enable engine server authentication SSL/TLS
# default is true
engine_tls = true
tlsenginecacertfile = /etc/atuned/engine_certs/ca.crt
tlsengineclientcertfile = /etc/atuned/engine_certs/client.crt
tlsengineclientkeyfile = /etc/atuned/engine_certs/client.key
tlsengineservercertfile = /etc/atuned/engine_certs/server.crt
tlsengineserverkeyfile = /etc/atuned/engine_certs/server.key
#################################### log ###############################
[log]
......
......@@ -231,7 +231,10 @@ func Post(serviceType, paramName, path string) (string, error) {
return "", fmt.Errorf("newRequest failed")
}
request.Header.Set("Content-Type", writer.FormDataContentType())
client := &HTTP.Client{}
client, err := http.NewhttpClient(url)
if err != nil {
return "", err
}
resp, err := client.Do(request)
if err != nil {
return "", fmt.Errorf("do request error")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册