tlsconf.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package control
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "path/filepath"
  6. log "github.com/Sirupsen/logrus"
  7. "github.com/codegangsta/cli"
  8. machineUtil "github.com/docker/machine/utils"
  9. "github.com/rancher/os/config"
  10. "github.com/rancher/os/util"
  11. )
  12. const (
  13. NAME string = "rancher"
  14. BITS int = 2048
  15. ServerTlsPath string = "/etc/docker/tls"
  16. ClientTlsPath string = "/home/rancher/.docker"
  17. Cert string = "cert.pem"
  18. Key string = "key.pem"
  19. ServerCert string = "server-cert.pem"
  20. ServerKey string = "server-key.pem"
  21. CaCert string = "ca.pem"
  22. CaKey string = "ca-key.pem"
  23. )
  24. func tlsConfCommands() []cli.Command {
  25. return []cli.Command{
  26. {
  27. Name: "generate",
  28. ShortName: "gen",
  29. Usage: "generates new set of TLS configuration certs",
  30. Action: tlsConfCreate,
  31. Flags: []cli.Flag{
  32. cli.StringSliceFlag{
  33. Name: "hostname, H",
  34. Usage: "the hostname for which you want to generate the certificate",
  35. Value: &cli.StringSlice{"localhost"},
  36. },
  37. cli.BoolFlag{
  38. Name: "server, s",
  39. Usage: "generate the server keys instead of client keys",
  40. },
  41. cli.StringFlag{
  42. Name: "dir, d",
  43. Usage: "the directory to save/read the certs to/from",
  44. Value: "",
  45. },
  46. },
  47. },
  48. }
  49. }
  50. func writeCerts(generateServer bool, hostname []string, certPath, keyPath, caCertPath, caKeyPath string) error {
  51. if !generateServer {
  52. return machineUtil.GenerateCert([]string{""}, certPath, keyPath, caCertPath, caKeyPath, NAME, BITS)
  53. }
  54. if err := machineUtil.GenerateCert(hostname, certPath, keyPath, caCertPath, caKeyPath, NAME, BITS); err != nil {
  55. return err
  56. }
  57. cert, err := ioutil.ReadFile(certPath)
  58. if err != nil {
  59. return err
  60. }
  61. key, err := ioutil.ReadFile(keyPath)
  62. if err != nil {
  63. return err
  64. }
  65. // certPath, keyPath are already written to by machineUtil.GenerateCert()
  66. if err := config.Set("rancher.docker.server_cert", string(cert)); err != nil {
  67. return err
  68. }
  69. if err := config.Set("rancher.docker.server_key", string(key)); err != nil {
  70. return err
  71. }
  72. return nil
  73. }
  74. func writeCaCerts(cfg *config.CloudConfig, caCertPath, caKeyPath string) error {
  75. if cfg.Rancher.Docker.CACert == "" {
  76. if err := machineUtil.GenerateCACertificate(caCertPath, caKeyPath, NAME, BITS); err != nil {
  77. return err
  78. }
  79. caCert, err := ioutil.ReadFile(caCertPath)
  80. if err != nil {
  81. return err
  82. }
  83. caKey, err := ioutil.ReadFile(caKeyPath)
  84. if err != nil {
  85. return err
  86. }
  87. // caCertPath, caKeyPath are already written to by machineUtil.GenerateCACertificate()
  88. if err := config.Set("rancher.docker.ca_cert", string(caCert)); err != nil {
  89. return err
  90. }
  91. if err := config.Set("rancher.docker.ca_key", string(caKey)); err != nil {
  92. return err
  93. }
  94. } else {
  95. cfg = config.LoadConfig()
  96. if err := util.WriteFileAtomic(caCertPath, []byte(cfg.Rancher.Docker.CACert), 0400); err != nil {
  97. return err
  98. }
  99. if err := util.WriteFileAtomic(caKeyPath, []byte(cfg.Rancher.Docker.CAKey), 0400); err != nil {
  100. return err
  101. }
  102. }
  103. return nil
  104. }
  105. func tlsConfCreate(c *cli.Context) error {
  106. err := generate(c)
  107. if err != nil {
  108. log.Fatal(err)
  109. }
  110. return nil
  111. }
  112. func generate(c *cli.Context) error {
  113. generateServer := c.Bool("server")
  114. outDir := c.String("dir")
  115. hostnames := c.StringSlice("hostname")
  116. return Generate(generateServer, outDir, hostnames)
  117. }
  118. func Generate(generateServer bool, outDir string, hostnames []string) error {
  119. if outDir == "" {
  120. if generateServer {
  121. outDir = ServerTlsPath
  122. } else {
  123. outDir = ClientTlsPath
  124. }
  125. log.Infof("Out directory (-d, --dir) not specified, using default: %s", outDir)
  126. }
  127. caCertPath := filepath.Join(outDir, CaCert)
  128. caKeyPath := filepath.Join(outDir, CaKey)
  129. certPath := filepath.Join(outDir, Cert)
  130. keyPath := filepath.Join(outDir, Key)
  131. if generateServer {
  132. certPath = filepath.Join(outDir, ServerCert)
  133. keyPath = filepath.Join(outDir, ServerKey)
  134. }
  135. if _, err := os.Stat(outDir); os.IsNotExist(err) {
  136. if err := os.MkdirAll(outDir, 0700); err != nil {
  137. return err
  138. }
  139. }
  140. cfg := config.LoadConfig()
  141. if err := writeCaCerts(cfg, caCertPath, caKeyPath); err != nil {
  142. return err
  143. }
  144. if err := writeCerts(generateServer, hostnames, certPath, keyPath, caCertPath, caKeyPath); err != nil {
  145. return err
  146. }
  147. if !generateServer {
  148. if err := filepath.Walk(outDir, func(path string, info os.FileInfo, err error) error {
  149. return os.Chown(path, 1100, 1100) // rancher:rancher
  150. }); err != nil {
  151. return err
  152. }
  153. }
  154. return nil
  155. }