You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
3.1 KiB

  1. #!/bin/sh
  2. #
  3. # see:
  4. # https://www.howtoforge.com/tutorial/strongswan-based-ipsec-vpn-using-certificates-and-pre-shared-key-on-ubuntu-16-04/
  5. #
  6. PROG=$(basename "$0")
  7. [ -z "$EUID" ] && EUID=$(id -u)
  8. if [ $# -lt 5 ]; then
  9. echo "Usage: $PROG { -s | -c | -u } country domain organization identities [ ... ]" >&2
  10. exit 1
  11. fi
  12. case "$1" in
  13. -s)
  14. S_OPT=1 ;;
  15. -c)
  16. C_OPT=1 ;;
  17. -u)
  18. U_OPT=1 ;;
  19. *)
  20. echo "$PROG: require an option specifying server/client/user credential type" >&2
  21. exit 1
  22. ;;
  23. esac
  24. shift
  25. C="$1"; shift
  26. DOMAIN="$1"; shift
  27. SHORT_DOMAIN="${DOMAIN%%.*}"
  28. ORG="$1"; shift
  29. # invariants...
  30. SYSCONFDIR=/etc
  31. SWANCTL_DIR="$SYSCONFDIR/swanctl"
  32. : ${KEYINFO:="rsa:4096"}
  33. : ${CADAYS:=3650}
  34. : ${CRTDAYS:=730}
  35. makeDN()
  36. {
  37. printf "C=%s, O=%s, CN=%s" "$1" "$2" "$3"
  38. }
  39. field()
  40. {
  41. local arg="$1"
  42. local nth="$2"
  43. echo "$arg" | cut -d ':' -f "$nth"
  44. }
  45. genmasterkey()
  46. {
  47. local keytype keybits
  48. keytype=$(field "$KEYINFO" 1)
  49. keybits=$(field "$KEYINFO" 2)
  50. pki --gen --type "$keytype" --size "$keybits" --outform pem > "$SWANCTL_DIR/private/$SHORT_DOMAIN.key"
  51. chmod 0400 "$SWANCTL_DIR/private/$SHORT_DOMAIN.key"
  52. }
  53. genca()
  54. {
  55. local keytype
  56. keytype=$(field "$KEYINFO" 1)
  57. pki --self --ca --lifetime "$CADAYS" --in "$SWANCTL_DIR/private/$SHORT_DOMAIN.key" --type "$keytype" \
  58. --dn "$ROOTDN" --outform pem > "$SWANCTL_DIR/x509ca/$SHORT_DOMAIN.crt"
  59. chmod 0444 "$SWANCTL_DIR/x509ca/$SHORT_DOMAIN.crt"
  60. }
  61. genclientkey()
  62. {
  63. local name="$1" keytype keybits
  64. keytype=$(field "$KEYINFO" 1)
  65. keybits=$(field "$KEYINFO" 2)
  66. pki --gen --type "$keytype" --size "$keybits" --outform pem > "$SWANCTL_DIR/private/$name.key"
  67. chmod 0400 "$SWANCTL_DIR/private/$name.key"
  68. }
  69. gendevcert()
  70. {
  71. local dn="$1"
  72. local san="$2"
  73. local name="$3"
  74. # reads key from input
  75. pki --issue --lifetime "$CRTDAYS" \
  76. --cacert "$SWANCTL_DIR/x509ca/$SHORT_DOMAIN.crt" \
  77. --cakey "$SWANCTL_DIR/private/$SHORT_DOMAIN.key" \
  78. --dn "$dn" --san "$san" \
  79. ${S_OPT:+--flag serverAuth} \
  80. ${S_OPT:---flag clientAuth} \
  81. --flag ikeIntermediate \
  82. --outform pem > "$SWANCTL_DIR/x509/$name.crt"
  83. chmod 0444 "$SWANCTL_DIR/x509/$name.crt"
  84. }
  85. gendev()
  86. {
  87. local keytype
  88. keytype=$(field "$KEYINFO" 1)
  89. [ -f "$SWANCTL_DIR/private/$NAME.key" ] || genclientkey "$NAME"
  90. [ -f "$SWANCTL_DIR/x509/$NAME.crt" ] || \
  91. pki --pub --in "$SWANCTL_DIR/private/$NAME.key" --type "$keytype" \
  92. | gendevcert "$DEVDN" "$DEVSAN" "$NAME"
  93. }
  94. setparams()
  95. {
  96. NAME="$1"
  97. if [ -n "$U_OPT" ]; then
  98. DEVSAN="$NAME@$DOMAIN"
  99. DEVDN="$(makeDN "$C" "$ORG" "$DEVSAN")"
  100. else
  101. DEVSAN="$NAME.$DOMAIN"
  102. DEVDN="$(makeDN "$C" "$ORG" "$NAME")"
  103. fi
  104. }
  105. umask 077
  106. [ "$EUID" -eq 0 ] || { echo "Must run as root!" >&2 ; exit 1; }
  107. ROOTDN="$(makeDN "$C" "$ORG" "Root CA")"
  108. [ -f "$SWANCTL_DIR/private/$SHORT_DOMAIN.key" ] || genmasterkey
  109. [ -f "$SWANCTL_DIR/x509ca/$SHORT_DOMAIN.crt" ] || genca
  110. PARENT="$SYSCONFDIR"
  111. BASEDIR="${SWANCTL_DIR##$PARENT/}"
  112. for name in "$@"; do
  113. setparams "$name"
  114. gendev
  115. tar -zcf "$name-certs.tar.gz" -C "$PARENT" "$BASEDIR/x509ca/$SHORT_DOMAIN.crt" "$BASEDIR/x509/$name.crt" "$BASEDIR/private/$name.key"
  116. chmod 600 "$name-certs.tar.gz"
  117. echo "Generated as $name-certs.tar.gz"
  118. done
  119. exit 0