[ADD] create cert automaticlly

This commit is contained in:
GLYASAI 2018-12-03 13:52:48 +08:00
parent 6546bb536a
commit 4eeb569304
4 changed files with 295 additions and 19 deletions

View File

@ -87,12 +87,12 @@ func mavenGoodrainMe() (*model.Server, *model.Upstream) {
return svr, us
}
func goodrainMe() (*model.Server, *model.Upstream) {
func goodrainMe(cfgPath string) (*model.Server, *model.Upstream) {
svr := &model.Server{
Listen: fmt.Sprintf("%s:%d %s", "0.0.0.0", 443, "ssl"),
ServerName: "goodrain.me",
SSLCertificate: "cert/server.crt",
SSLCertificateKey: "cert/server.key",
SSLCertificate: fmt.Sprintf("%s/%s", cfgPath, "ssl/server.crt"),
SSLCertificateKey: fmt.Sprintf("%s/%s", cfgPath, "ssl/server.key"),
ClientMaxBodySize: model.Size{Num:0, Unit:"k"},
ChunkedTransferEncoding: true,
Locations: []*model.Location{

View File

@ -2,8 +2,11 @@ package openresty
import (
"bytes"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/json"
"fmt"
"github.com/goodrain/rainbond/util/cert"
"net/http"
"os"
"path"
@ -76,11 +79,11 @@ func (osvc *OrService) Start(errCh chan error) {
errCh <- fmt.Errorf("Can't not new nginx config: %s", err.Error())
return
}
// if osvc.config.EnableRbdEndpoints {
// if err := osvc.newRbdServers(); err != nil {
// errCh <- err // TODO: consider if it is right
// }
// }
if osvc.config.EnableRbdEndpoints {
if err := osvc.newRbdServers(); err != nil {
errCh <- err // TODO: consider if it is right
}
}
cmd := nginxExecCommand()
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@ -94,7 +97,7 @@ func (osvc *OrService) Start(errCh chan error) {
if err := cmd.Wait(); err != nil {
errCh <- err
}
errCh <- fmt.Errorf("nginx process is exit")
//errCh <- fmt.Errorf("nginx process is exit")
}()
}
@ -280,9 +283,15 @@ func (osvc *OrService) newRbdServers() error {
return err
}
lesrv, leus := langGoodrainMe()
mesrv, meus := mavenGoodrainMe()
gesrv, geus := goodrainMe()
// create cert
err := createCert(cfgPath, "goodrain.me")
if err != nil {
return err
}
lesrv, _ := langGoodrainMe()
mesrv, _ := mavenGoodrainMe()
gesrv, _ := goodrainMe(cfgPath)
if err := template.NewServerTemplateWithCfgPath([]*model.Server{
lesrv,
mesrv,
@ -292,12 +301,50 @@ func (osvc *OrService) newRbdServers() error {
}
// upstreams
if err := template.NewUpstreamTemplateWithCfgPath([]*model.Upstream{
leus,
meus,
geus,
}, "upstreams-http-rbd.tmpl", cfgPath, "upstreams.default.http.conf"); err != nil {
return err
}
//if err := template.NewUpstreamTemplateWithCfgPath([]*model.Upstream{
// leus,
// meus,
// geus,
//}, "upstreams-http-rbd.tmpl", cfgPath, "upstreams.default.http.conf"); err != nil {
// return err
//}
return nil
}
func createCert(cfgPath string, cn string) error {
if e := os.MkdirAll(fmt.Sprintf("%s/%s", cfgPath, "ssl"), 0777); e != nil {
return e
}
baseinfo := cert.CertInformation{Country: []string{"CN"}, Organization: []string{"Goodrain"}, IsCA: true,
OrganizationalUnit: []string{"Rainbond"}, EmailAddress: []string{"zengqg@goodrain.com"},
Locality: []string{"BeiJing"}, Province: []string{"BeiJing"}, CommonName: cn,
Domains: []string{"goodrain.me"},
CrtName: fmt.Sprintf("%s/%s", cfgPath, "ssl/ca.pem"),
KeyName: fmt.Sprintf("%s/%s", cfgPath, "ssl/ca.key")}
err := cert.CreateCRT(nil, nil, baseinfo)
if err != nil {
logrus.Errorf("Create crt error: ", err)
return err
}
crtInfo := baseinfo
crtInfo.IsCA = false
crtInfo.CrtName = fmt.Sprintf("%s/%s", cfgPath, "ssl/server.crt")
crtInfo.KeyName = fmt.Sprintf("%s/%s", cfgPath, "ssl/server.key")
crtInfo.Names = []pkix.AttributeTypeAndValue{{asn1.ObjectIdentifier{2, 1, 3}, "MAC_ADDR"}}
crt, pri, err := cert.Parse(baseinfo.CrtName, baseinfo.KeyName)
if err != nil {
logrus.Errorf("Parse crt error,Error info:", err)
return err
}
err = cert.CreateCRT(crt, pri, crtInfo)
if err != nil {
logrus.Errorf("Create crt error,Error info:", err)
return err
}
logrus.Info("Create certificate for goodrain.me successfully")
return nil
}

172
util/cert/certutil.go Normal file
View File

@ -0,0 +1,172 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package cert
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"io/ioutil"
"math/big"
rd "math/rand"
"net"
"os"
"time"
)
func init() {
rd.Seed(time.Now().UnixNano())
}
type CertInformation struct {
Country []string
Organization []string
OrganizationalUnit []string
EmailAddress []string
Province []string
Locality []string
CommonName string
CrtName, KeyName string
IsCA bool
Names []pkix.AttributeTypeAndValue
IPAddresses []net.IP
Domains []string
}
//CreateCRT create crt
func CreateCRT(RootCa *x509.Certificate, RootKey *rsa.PrivateKey, info CertInformation) error {
Crt := newCertificate(info)
Key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return err
}
var buf []byte
if RootCa == nil || RootKey == nil {
//create ca cert
buf, err = x509.CreateCertificate(rand.Reader, Crt, Crt, &Key.PublicKey, Key)
if err != nil {
return err
}
keybuf := x509.MarshalPKCS1PrivateKey(Key)
err = write(info.KeyName, "PRIVATE KEY", keybuf)
} else {
//create cert by ca
buf, err = x509.CreateCertificate(rand.Reader, Crt, RootCa, &Key.PublicKey, RootKey)
if err != nil {
return err
}
keybuf := x509.MarshalPKCS1PrivateKey(Key)
err = write(info.KeyName, "RSA PRIVATE KEY", keybuf)
}
if err != nil {
return err
}
err = write(info.CrtName, "CERTIFICATE", buf)
if err != nil {
return err
}
return nil
}
//编码写入文件
func write(filename, Type string, p []byte) error {
File, err := os.Create(filename)
defer File.Close()
if err != nil {
return err
}
var b = &pem.Block{Bytes: p, Type: Type}
return pem.Encode(File, b)
}
//Parse Parse
func Parse(crtPath, keyPath string) (rootcertificate *x509.Certificate, rootPrivateKey *rsa.PrivateKey, err error) {
rootcertificate, err = ParseCrt(crtPath)
if err != nil {
return
}
rootPrivateKey, err = ParseKey(keyPath)
return
}
//ParseCrt ParseCrt
func ParseCrt(path string) (*x509.Certificate, error) {
buf, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
p := &pem.Block{}
p, buf = pem.Decode(buf)
return x509.ParseCertificate(p.Bytes)
}
//ParseKey ParseKey
func ParseKey(path string) (*rsa.PrivateKey, error) {
buf, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
p, buf := pem.Decode(buf)
return x509.ParsePKCS1PrivateKey(p.Bytes)
}
func newCertificate(info CertInformation) *x509.Certificate {
return &x509.Certificate{
SerialNumber: big.NewInt(rd.Int63()),
Subject: pkix.Name{
Country: info.Country,
Organization: info.Organization,
OrganizationalUnit: info.OrganizationalUnit,
Province: info.Province,
CommonName: info.CommonName,
Locality: info.Locality,
ExtraNames: info.Names,
},
NotBefore: time.Now(), //start time
NotAfter: time.Now().AddDate(20, 0, 0), //end time
BasicConstraintsValid: true, //basic
IsCA: info.IsCA, //是否是根证书
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, //证书用途
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
EmailAddresses: info.EmailAddress,
IPAddresses: info.IPAddresses,
DNSNames: info.Domains,
}
}
//CreateCertInformation CreateCertInformation
func CreateCertInformation() CertInformation {
baseinfo := CertInformation{
Country: []string{"CN"},
Organization: []string{"Goodrain"},
OrganizationalUnit: []string{"goodrain rainbond"},
EmailAddress: []string{"zengqg@goodrain.com"},
Locality: []string{"BeiJing"},
Province: []string{"BeiJing"},
CommonName: "rainbond",
CrtName: "",
KeyName: "",
Domains: []string{"goodrain.me"},
}
baseinfo.IPAddresses = []net.IP{net.ParseIP("127.0.0.1")}
return baseinfo
}

View File

@ -0,0 +1,57 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package cert
import (
"crypto/x509/pkix"
"encoding/asn1"
"testing"
)
func Test_crt(t *testing.T) {
baseinfo := CertInformation{Country: []string{"CN"}, Organization: []string{"Goodrain"}, IsCA: true,
OrganizationalUnit: []string{"work-stacks"}, EmailAddress: []string{"zengqg@goodrain.com"},
Locality: []string{"BeiJing"}, Province: []string{"BeiJing"}, CommonName: "Work-Stacks",
Domains: []string{"goodrain.me"},CrtName: "../../test/ssl/ca.pem", KeyName: "../../test/ssl/ca.key"}
err := CreateCRT(nil, nil, baseinfo)
if err != nil {
t.Log("Create crt error,Error info:", err)
return
}
crtinfo := baseinfo
crtinfo.IsCA = false
crtinfo.CrtName = "../../test/ssl/api_server.pem"
crtinfo.KeyName = "../../test/ssl/api_server.key"
crtinfo.Names = []pkix.AttributeTypeAndValue{{asn1.ObjectIdentifier{2, 1, 3}, "MAC_ADDR"}}
crt, pri, err := Parse(baseinfo.CrtName, baseinfo.KeyName)
if err != nil {
t.Log("Parse crt error,Error info:", err)
return
}
err = CreateCRT(crt, pri, crtinfo)
if err != nil {
t.Log("Create crt error,Error info:", err)
}
//os.Remove(baseinfo.CrtName)
//os.Remove(baseinfo.KeyName)
//os.Remove(crtinfo.CrtName)
//os.Remove(crtinfo.KeyName)
}