mirror of
https://gitee.com/rainbond/Rainbond.git
synced 2024-12-02 19:57:42 +08:00
[ADD] create cert automaticlly
This commit is contained in:
parent
6546bb536a
commit
4eeb569304
@ -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{
|
||||
|
@ -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
172
util/cert/certutil.go
Normal 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
|
||||
}
|
57
util/cert/certutil_test.go
Normal file
57
util/cert/certutil_test.go
Normal 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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user