├── LICENSE
├── README.md
├── bootstrap
├── 01-init-bastion-host.sh
├── 02-init-internal-dns.sh
├── 03-init-openvpn.sh
├── 04-init-kops.sh
├── 05-init-kubernetes-dashboard.sh
├── alb-dns-external.yaml
├── alb-ingress-301-redirection-example.yaml
├── alb-ingress-controller.yaml
├── apache2-dashboard-init-with-http-redirect.conf
├── banner_message.txt
├── bastion-bootstrap.sh
├── cluster-autoscaler.yml
├── kops-cluster-additionalpolicies.json
├── kops-sharedvpc-iam-yamlconfig.py
├── kubernetes-dashboard.yaml
├── kubernetes-monitoring.yaml
├── purge-s3-versioned-bucket.py
└── tear-down-cluster.sh
├── cfn-templates
├── latest-single-natinstance.yaml
└── tc2-kuberntes-on-aws-v1.15.yaml
├── deploy-s3.sh
├── docs
├── TC2_Abstratct_production_grade_Kubernetes_deployment_on_AWS.pdf
├── k8s-fullscale.png
└── k8s-small-footprint.png
└── easy-openvpn
├── README.md
└── keygen
├── build-ca
├── build-crl-revoke
├── build-dh
├── build-inter
├── build-key
├── build-key-embed
├── build-key-embed-commongw
├── build-key-pkcs12
├── build-key-pkcs12-commongw
├── build-key-server
├── build-key-server-tcp-commongw
├── build-req
├── build-req-pass
├── build-ta
├── ccd
├── ccd-tcp
├── clean-all
├── client-template-embed-commongw.ovpn
├── client-template-embed.ovpn
├── client-template.commongw.p12.ovpn
├── client-template.ovpn
├── client-template.p12.ovpn
├── create-server
├── create-server-tcp-gw
├── inherit-inter
├── list-crl
├── openssl-0.9.6.cnf
├── openssl-0.9.8.cnf
├── openssl-1.0.0.cnf
├── pem-split
├── pkitool
├── revoke-client
├── server-startup-template-tcp-gw.sh
├── server-startup-template.sh
├── server-template-tcp-commongw.conf
├── server-template.conf
├── sign-req
├── vars
└── whichopensslcnf
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AWS Quick Start: Production grade Kubernetes cluster deployment on AWS cloud
2 |
3 | This AWS Quick-Start ("one-click solution") based on AWS CloudFormation templates and scripts set up a flexible, secure, fault-tolerant Kubernetes cluster in AWS private VPC environment, into a configuration of your choice. The project main purposes are: quick, simple, painless, easy Kubernetes environment deployment in 10 minutes.
4 |
5 | Our solution based on Kubernetes Operations ("kops") combined with AWS CloudFormation (CFN) templates together with bootstrap scripts, help to automate the whole process. The final result is a 100% compatible Kubernetes cluster, what you can manage from either the Bastion host, via OpenVPN or using it's HTTPS API through AWS ELB endpoint.
6 |
7 | We always keep focus on security, transparency and simplicity. This guide is mainly created for developers, IT architects, administrators, and DevOps professionals who are planning to easily deploy their Kubernetes workloads on AWS.
8 |
9 |
10 | # Architecture
11 |
12 | [](https://totalcloudconsulting.hu/en/solutions/containerization)
13 |
14 |
15 | [AWS Quick-Start Launch](https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?stackName=Total-Cloud-Kubernetes&templateURL=https://s3-eu-west-1.amazonaws.com/tc2-kubernetes/latest/cfn-templates/latest-single-natinstance.yaml )
16 |
17 | ## Resources deployed
18 |
19 | * one new VPC: 3 private and 3 public subnets in 3 different Availability Zones, Gateway type Private Link routes to S3 and DynamoDB (free),
20 | * one self-healing Kubernetes Master instance in one Availability Zone's private subnet,
21 | * auto-scalable Node instances in AutoScaling groups, expended over all Availability Zones,
22 | * one self-healing bastion host in 1 Availability Zone's public subnet, bastion host is the NAT instance router for private subnets,
23 | * one Elastic IP Address (EIP) for bastion host,
24 | * one internal (or public: optional) ELB load balancer for HTTPS access to the Kubernetes API server,
25 | * two CloudWatch Logs group for bastion host and Kubernetes Docker pods (optional),
26 | * one Lambda function for graceful teardown with AWS SSM,
27 | * two security groups: 1 for bastion host, 1 for Kubernetes Hosts (Master and Nodes)
28 | * IAM roles for bastion hosts, K8s Nodes and Master hosts
29 | * one S3 bucket for kops state store,
30 | * one Route53 private zone for VPC (optional),
31 | * OpenVPN service with auto-generated keys on bastion host (optional)
32 | * AWS EFS mounted on bastion in all AZs
33 | * optional ALB ingress controller with external (Route53) domain management
34 |
35 | # How To build your cluster
36 |
37 | * Sign up for an AWS account at https://aws.amazon.com. then sign in with proper rights (IAM full rights are required)
38 |
39 | Create the Kubernetes cluster:
40 |
41 | [AWS Quick-Start Launch](https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?stackName=Total-Cloud-Kubernetes&templateURL=https://s3-eu-west-1.amazonaws.com/tc2-kubernetes/latest/cfn-templates/latest-single-natinstance.yaml )
42 |
43 |
44 | **The cluster (via bastion host) creation lasts around 10-15 minutes, please be patient.**
45 |
46 | * Connect to your Kubernetes cluster by following the step-by-step instructions in the deployment guide.
47 |
48 | To customize your deployment, you can choose different instance types for the Kubernetes cluster and the bastion host, choose the number of worker nodes, API endpoint type, logging option, OpenVPN install, plug-ins.
49 |
50 | For detailed instructions, see the deployment guide.
51 |
52 |
53 | The cluster (via bastion host) creation lasts around 10 minutes, please be patient.
54 |
55 | **After the clutser has been created, just connect to the bastion host via SSH, the "kops", "kubectl" and "helm" commands working out-of-the box, no extras steps needed!**
56 |
57 | # Abstract paper
58 |
59 | Have a look at [this abstract paper](docs/TC2_Abstratct_production_grade_Kubernetes_deployment_on_AWS.pdf) for the high level details of this solution.
60 |
61 | # Visit us
62 |
63 | https://totalcloudconsulting.hu/en/solutions
64 |
65 | # References
66 |
67 | * Kubernetes Open-Source Documentation: https://kubernetes.io/docs/
68 | * Calico Networking: http://docs.projectcalico.org/
69 | * KOPS documentation: https://github.com/kubernetes/kops/blob/master/docs/aws.md , https://github.com/kubernetes/kops/tree/master/docs
70 | * Kubernetes Host OS versions: https://github.com/kubernetes/kops/blob/master/docs/images.md
71 | * OpenVPN: https://github.com/tatobi/easy-openvpn
72 | * ALB ingress controller: https://github.com/kubernetes-sigs/aws-alb-ingress-controller
73 |
74 | # Costs and licenses
75 |
76 | You are responsible for the cost of the AWS services used while running this deployment. Our project hosted under Apache 2.0 open source license.
77 |
--------------------------------------------------------------------------------
/bootstrap/01-init-bastion-host.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "#################"
4 | echo "INIT-BASTION-HOST START..."
5 |
6 | S3BootstrapBucketName=${1}
7 | S3BootstrapBucketPrefix=${2}
8 | AWSRegion=${3}
9 | VPCIPv4CIDRBlock=${4}
10 |
11 | #install modified AWS Bastion bootstrap
12 | export BASTION_BOOTSTRAP_FILE=bastion-bootstrap.sh
13 |
14 | cp banner_message.txt /etc/ssh_banner
15 |
16 | main_interface=`ip r sh | grep default | awk '{print $5}'`
17 |
18 | iptables -t nat -A POSTROUTING -s ${VPCIPv4CIDRBlock} -o ${main_interface} -j MASQUERADE
19 | echo 1 > /proc/sys/net/ipv4/ip_forward
20 |
21 | sysctl -w net.ipv4.ip_forward=1
22 | echo 'net.ipv4.ip_forward = 1' | tee --append /etc/sysctl.conf
23 |
24 | echo '#!/bin/sh -e' | tee /etc/rc.local
25 | echo '' | tee --append /etc/rc.local
26 | echo "iptables -t nat -A POSTROUTING -s ${VPCIPv4CIDRBlock} -o ${main_interface} -j MASQUERADE" | tee --append /etc/rc.local
27 | echo 'exit 0' | tee --append /etc/rc.local
28 |
29 | chmod +x $BASTION_BOOTSTRAP_FILE
30 | ./$BASTION_BOOTSTRAP_FILE --banner banner_message.txt --enable true > ./bastion-bootstrap.log 2>&1 || exit 0
31 |
32 | sleep 5
33 |
34 | echo "INIT-BASTION-HOST DONE."
35 | echo "#################"
36 | exit 0
37 |
--------------------------------------------------------------------------------
/bootstrap/02-init-internal-dns.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | AWSRegion=${1}
4 | VPC=${2}
5 | KubernetesAPIPublicAccess=${3}
6 | AWSCfnStackName=${4}
7 |
8 |
9 | echo "#################"
10 | echo "START INIT-INTERNAL-DNS..."
11 |
12 | randomstuff=`cat /dev/urandom | tr -dc 'a-z0-9' | head -c 8`
13 | stacklower=`echo "${AWSCfnStackName}" | tr '[:upper:]' '[:lower:]'`
14 |
15 | if [[ "${KubernetesAPIPublicAccess}" == "false" ]];
16 | then
17 | K8sRoute53ZoneName="${stacklower}-${randomstuff}.internal"
18 | echo "K8s Internal DNS Zone name is: ${K8sRoute53ZoneName}"
19 | echo ${K8sRoute53ZoneName} > /opt/kops-state/KOPS_VPC_R53_ZONE_DNS
20 |
21 | aws route53 create-hosted-zone --name ${K8sRoute53ZoneName} --vpc VPCRegion=${AWSRegion},VPCId=${VPC} --hosted-zone-config Comment="${AWSCfnStackName}-Kubernetes",PrivateZone=true --region ${AWSRegion} --caller-reference "`date`" --output text | grep "hostedzone/" | grep "https://route53.amazonaws.com" | cut -d '/' -f 6 > /opt/kops-state/KOPS_R53_PRIVATE_HOSTED_ZONE_ID
22 | fi
23 |
24 | echo "DONE START INIT-INTERNAL-DNS."
25 | echo "#################"
26 | exit 0
27 |
--------------------------------------------------------------------------------
/bootstrap/03-init-openvpn.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "#################"
4 | echo "INIT-OPENVPN START..."
5 |
6 | VPCIPv4CIDRBlock=${1}
7 | VPNCACountryISOCode=${2}
8 | VPNCAProvince=${3}
9 | VPNCACity=${4}
10 | VPNCAOrganization=${5}
11 | VPNCAOrgEmail=${6}
12 | VPNCAOrgUnit=${7}
13 | VPNNumberOfPreGeneratedCerts=${8}
14 | K8sClusterName=${9}
15 |
16 | mv /opt/easy-openvpn/keygen /etc/openvpn/
17 | cd /etc/openvpn/keygen
18 | chmod +x /etc/openvpn/keygen/*
19 |
20 | R53PrivateDNSZoneName=""
21 | if [[ -e "/opt/kops-state/KOPS_VPC_R53_ZONE_DNS" ]];
22 | then
23 | R53PrivateDNSZoneName=`cat /opt/kops-state/KOPS_VPC_R53_ZONE_DNS`
24 | fi
25 |
26 | export openvpnvars="/etc/openvpn/keygen/vars"
27 |
28 | ip=`curl http://169.254.169.254/latest/meta-data/public-ipv4`
29 | awsdns=$(echo $VPCIPv4CIDRBlock | tr "." " " | awk '{ print $1"."$2"."$3".2" }')
30 |
31 | echo ${ip}
32 | echo ${awsdns}
33 |
34 | sed -i 's/CHANGE_SERVER_IP/'${ip}'/g' ${openvpnvars}
35 | sed -i 's/CC/'${VPNCACountryISOCode}'/g' ${openvpnvars}
36 | sed -i 's/CHANGE_PROVINCE/'${VPNCAProvince}'/g' ${openvpnvars}
37 | sed -i 's/CHANGE_CITY/'${VPNCACity}'/g' ${openvpnvars}
38 | sed -i 's/CHANGE_ORG/'${VPNCAOrganization}'/g' ${openvpnvars}
39 | sed -i 's/CHANGE_ORG_EMAIL/'${VPNCAOrgEmail}'/g' ${openvpnvars}
40 | sed -i 's/CHANGE_OU/'${VPNCAOrgUnit}'/g' ${openvpnvars}
41 |
42 | echo "push \"route $VPCIPv4CIDRBlock 255.255.0.0\"" | tee --append server-template.conf
43 | echo "push \"register-dns\"" | tee --append server-template.conf
44 |
45 | if [[ -n ${R53PrivateDNSZoneName} ]];
46 | then
47 | echo "push \"dhcp-option DNS __REPLACE_AWS_DNS__\"" | tee --append server-template.conf
48 | echo "push \"dhcp-option DOMAIN $R53PrivateDNSZoneName\"" | tee --append server-template.conf
49 | sed -i 's/__REPLACE_AWS_DNS__/'${awsdns}'/g' server-template.conf
50 | fi
51 |
52 | ./create-server
53 | service openvpn@server start
54 | systemctl enable openvpn@server
55 |
56 | #set options in client file for tunnelblick
57 | echo "dhcp-option DNS ${awsdns}" | tee --append client-template-embed.ovpn
58 | echo "dhcp-option DOMAIN $R53PrivateDNSZoneName" | tee --append client-template-embed.ovpn
59 |
60 | i=1
61 | while [[ "$i" -le "${VPNNumberOfPreGeneratedCerts}" ]];
62 | do
63 | ./build-key-embed "K8s.OVPNkey.${K8sClusterName}.${i}.org";
64 | cp /etc/openvpn/keys/K8s.OVPNkey.${K8sClusterName}.${i}.org/K8s.OVPNkey.${K8sClusterName}.${i}.org.ovpn /opt/openvpn-keys/;
65 | i=$((i + 1))
66 | done
67 |
68 | chown ubuntu:ubuntu /opt/openvpn-keys/*
69 |
70 | echo "INIT-OPENVPN DONE."
71 | echo "#################"
72 |
73 | exit 0
74 |
75 |
--------------------------------------------------------------------------------
/bootstrap/04-init-kops.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | AWSRegion=${1}
4 | AWSCfnStackName=${2}
5 | Ec2K8sMasterInstanceType=${3}
6 | Ec2K8sNodeInstanceType=${4}
7 | Ec2K8sNodeCapacityMin=${5}
8 | Ec2K8sNodeCapacityMax=${6}
9 | Ec2EBSK8sDiskSizeGb=${7}
10 | Ec2K8sAMIOsType=${8}
11 | Ec2K8sMultiAZMaster=${9}
12 | VPC=${10}
13 | NetworkCIDR=${11}
14 | PrivateSubnet1=${12}
15 | PrivateSubnet2=${13}
16 | PrivateSubnet3=${14}
17 | PublicSubnet1=${15}
18 | PublicSubnet2=${16}
19 | PublicSubnet3=${17}
20 | K8sMasterAndNodeSecurityGroup=${18}
21 | S3BootstrapBucketName=${18}
22 | S3BootstrapBucketPrefix=${20}
23 | KubernetesDashboard=${21}
24 | KubernetesALBIngressController=${22}
25 | KubernetesClusterAutoscaler=${23}
26 | KubernetesAPIPublicAccess=${24}
27 | KubernetesExternalDNSPlugin=${25}
28 | KubernetesExternalDNSName=${26}
29 | KubernetesExternalDNSTXTSelector=${27}
30 | KOPSReleaseVersion=${28}
31 | KUBECTLReleaseVersion=${29}
32 | HELMReleaseVersion=${30}
33 | FORCED_AMI_ID=${31}
34 | NODES_SPOT_PRICE="0.0"
35 |
36 | echo "#################"
37 | echo "START INIT-KOPS."
38 |
39 | AWSCfnStackName=`echo "${AWSCfnStackName}" | tr '[:upper:]' '[:lower:]'`
40 | randomstuff=`cat /dev/urandom | tr -dc 'a-z0-9' | head -c 8`
41 |
42 |
43 | #sync kops, k8s binaries
44 | aws s3 sync s3://${S3BootstrapBucketName}/${S3BootstrapBucketPrefix}/bin/ /usr/local/bin/ --region ${AWSRegion} --quiet
45 |
46 | if [[ ! -e /usr/local/bin/kops ]];
47 | then
48 | echo "Download latest KOPS...";
49 | wget -O kops https://github.com/kubernetes/kops/releases/download/${KOPSReleaseVersion}/kops-linux-amd64 --no-verbose
50 | sudo mv ./kops /usr/local/bin/
51 | fi
52 |
53 | if [[ ! -e /usr/local/bin/kubectl ]];
54 | then
55 | echo "Download latest KUBECTL...";
56 | wget -O kubectl https://storage.googleapis.com/kubernetes-release/release/v${KUBECTLReleaseVersion}/bin/linux/amd64/kubectl --no-verbose
57 | mv ./kubectl /usr/local/bin/kubectl
58 | fi
59 |
60 | if [[ ! -e /usr/local/bin/helm ]];
61 | then
62 | echo "Download latest HELM...";
63 | wget -O helm.tar.gz https://storage.googleapis.com/kubernetes-helm/helm-v${HELMReleaseVersion}-linux-amd64.tar.gz --no-verbose
64 | tar -xf helm.tar.gz
65 | mv ./linux-amd64/helm /usr/local/bin/helm
66 | fi
67 |
68 | chmod +x /usr/local/bin/*
69 |
70 |
71 | #get zones
72 | subnetzone1=`aws ec2 describe-subnets --subnet-ids ${PrivateSubnet1} --output text --region ${AWSRegion} | grep 'SUBNETS' | awk '{print $3}'`
73 | echo "Zone1: ${subnetzone1}"
74 |
75 | subnetzone2=`aws ec2 describe-subnets --subnet-ids ${PrivateSubnet2} --output text --region ${AWSRegion} | grep 'SUBNETS' | awk '{print $3}'`
76 | echo "Zone2: ${subnetzone2}"
77 |
78 | #master_zones
79 | master_zones="--master-zones=${subnetzone1},${subnetzone2}"
80 |
81 | #node zones
82 | node_zones="--zones=${subnetzone1},${subnetzone2}"
83 |
84 | if [[ -n ${PrivateSubnet3} ]];
85 | then
86 | subnetzone3=`aws ec2 describe-subnets --subnet-ids ${PrivateSubnet3} --output text --region ${AWSRegion} | grep 'SUBNETS' | awk '{print $3}'`
87 | if [[ -n ${subnetzone3} ]];
88 | then
89 | echo "Zone3: ${subnetzone3}"
90 | master_zones="--master-zones=${subnetzone1},${subnetzone2},${subnetzone3}"
91 | node_zones="--zones=${subnetzone1},${subnetzone2},${subnetzone3}"
92 | fi
93 | fi
94 |
95 | K8sRoute53ZoneName="${AWSCfnStackName}.k8s.local"
96 | K8sClusterName=${K8sRoute53ZoneName}
97 | if [[ -e "/opt/kops-state/KOPS_VPC_R53_ZONE_DNS" ]];
98 | then
99 | K8sRoute53ZoneName=`cat /opt/kops-state/KOPS_VPC_R53_ZONE_DNS`
100 | K8sRoute53ZoneName=`echo "${K8sRoute53ZoneName}" | tr '[:upper:]' '[:lower:]'`
101 | K8sClusterName=${K8sRoute53ZoneName}
102 | else
103 | echo "ERROR: no internal zone found, using local gossip based dns: ${K8sRoute53ZoneName}"
104 | fi
105 |
106 | echo "K8sRoute53ZoneName: ${K8sRoute53ZoneName}"
107 | echo "K8sClusterName: ${K8sClusterName}"
108 |
109 | #create s3 bucket
110 | if [[ ! -e s3-kops-state.txt ]];
111 | then
112 | s3bucket="kops-state-${AWSCfnStackName}-${randomstuff}"
113 | echo "Create bucket: ${s3bucket}"
114 | echo ${s3bucket} > s3-kops-state.txt
115 | else
116 | s3bucket=`cat s3-kops-state.txt`
117 | fi
118 |
119 | echo "KOPS state S3 bucket: ${s3bucket}"
120 |
121 | export KOPS_STATE_STORE=s3://${s3bucket}
122 |
123 | echo ${VPC} >> /opt/kops-state/KOPS_VPC
124 |
125 | echo ${KOPS_STATE_STORE} > /opt/kops-state/KOPS_STATE_STORE
126 | echo ${PrivateSubnet1} > /opt/kops-state/KOPS_PRIVATE_SUBNETS
127 | echo ${PrivateSubnet2} >> /opt/kops-state/KOPS_PRIVATE_SUBNETS
128 |
129 | if [[ -n ${PrivateSubnet3} ]];
130 | then
131 | echo ${PrivateSubnet3} >> /opt/kops-state/KOPS_PRIVATE_SUBNETS
132 | fi
133 | echo ${K8sMasterAndNodeSecurityGroup} > /opt/kops-state/KOPS_SECURITY_GROUP
134 |
135 | echo ${PublicSubnet1} >> /opt/kops-state/KOPS_PUBLIC_SUBNETS
136 | echo ${PublicSubnet2} >> /opt/kops-state/KOPS_PUBLIC_SUBNETS
137 | echo ${PublicSubnet3} >> /opt/kops-state/KOPS_PUBLIC_SUBNETS
138 |
139 | #create kops state bucket
140 | if [[ "${AWSRegion}" == "us-east-1" ]];
141 | then
142 | aws s3api create-bucket --bucket ${s3bucket} --region ${AWSRegion}
143 | else
144 | aws s3api create-bucket --bucket ${s3bucket} --region ${AWSRegion} --create-bucket-configuration LocationConstraint=${AWSRegion}
145 | fi
146 |
147 | #switch on kops state bucket versioning
148 | aws s3api put-bucket-versioning --bucket ${s3bucket} --versioning-configuration Status=Enabled --region ${AWSRegion}
149 |
150 | #public key for kops
151 | pkey=`head -n1 /home/ubuntu/.ssh/authorized_keys`
152 | echo ${pkey} > id_rsa.pub
153 | chmod 600 id_rsa.pub
154 |
155 |
156 | #defione image for nodes
157 | #Debian Jessie is the default if no option
158 | k8s_ami=""
159 | host_ssl_certpath="/etc/ssl/certs/ca-certificates.crt"
160 | host_ssl_certdir="/etc/ssl/certs"
161 |
162 |
163 | if [ "${Ec2K8sAMIOsType}" == "Ubuntu-1604-LTS" ];
164 | then
165 | ami_ubuntu=`aws ec2 describe-images --owners 099720109477 --filters Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server* --query 'Images[*].[ImageId,CreationDate]' --output text --region ${AWSRegion} | sort -k2 -r | head -n1 | awk '{print $1}'`
166 | k8s_ami="--image=${ami_ubuntu}"
167 | fi
168 |
169 | if [ "${Ec2K8sAMIOsType}" == "Ubuntu-1804-LTS" ];
170 | then
171 | ami_ubuntu=`aws ec2 describe-images --owners 099720109477 --filters Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-xenial-18.04-amd64-server* --query 'Images[*].[ImageId,CreationDate]' --output text --region ${AWSRegion} | sort -k2 -r | head -n1 | awk '{print $1}'`
172 | k8s_ami="--image=${ami_ubuntu}"
173 | fi
174 |
175 | if [ "${Ec2K8sAMIOsType}" == "AmazonLinux2" ];
176 | then
177 | ami_ubuntu=`aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2" "Name=architecture,Values=x86_64" "Name=root-device-type,Values=ebs" --query 'Images[*].[ImageId,CreationDate]' --output text --region ${AWSRegion} | sort -k2 -r | head -n1 | awk '{print $1}'`
178 | k8s_ami="--image=${ami_ubuntu}"
179 | host_ssl_certpath="/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt"
180 | host_ssl_certdir="/etc/pki/ca-trust/extracted/pem"
181 | fi
182 |
183 | if [ "${Ec2K8sAMIOsType}" == "CentOS-7" ];
184 | then
185 | ami_centos=`aws ec2 describe-images --owners 410186602215 --filters "Name=virtualization-type,Values=hvm" "Name=name,Values=CentOS Linux 7 x86_64 HVM EBS*" --query 'Images[*].[ImageId,CreationDate]' --output text --region ${AWSRegion} | sort -k2 -r | head -n1 | awk '{print $1}'`
186 | k8s_ami="--image=${ami_centos}"
187 | host_ssl_certpath="/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt"
188 | host_ssl_certdir="/etc/pki/ca-trust/extracted/pem"
189 | fi
190 |
191 | if [ "${Ec2K8sAMIOsType}" == "RHEL-7" ];
192 | then
193 | ami_rhel7=`aws ec2 describe-images --owner=309956199498 --filters "Name=virtualization-type,Values=hvm" "Name=name,Values=RHEL-7.*" --query 'Images[*].[ImageId,CreationDate]' --output text --region ${AWSRegion} | sort -k2 -r | head -n1 | awk '{print $1}'`
194 | k8s_ami="--image=${ami_rhel7}"
195 | host_ssl_certpath="/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt"
196 | host_ssl_certdir="/etc/pki/ca-trust/extracted/pem"
197 | fi
198 |
199 | if [[ -n ${FORCED_AMI_ID} ]];
200 | then
201 | echo "FORCE AMI ID TO USE: ${FORCED_AMI_ID}"
202 | k8s_ami="--image=${FORCED_AMI_ID}"
203 | fi
204 |
205 | echo "Kubernetes Cluster AMI: ${k8s_ami}"
206 |
207 | #internal / external API
208 | api_lb_type="--api-loadbalancer-type=internal"
209 | dns_zone="--dns-zone=${K8sRoute53ZoneName}"
210 | dns="--dns=private"
211 | if [[ "${KubernetesAPIPublicAccess}" == "true" ]];
212 | then
213 | echo "K8s API LB is Public, using Gossip DNS configuration ..."
214 | api_lb_type="--api-loadbalancer-type=public"
215 | dns_zone=""
216 | dns=""
217 | K8sClusterName="${AWSCfnStackName}.k8s.local"
218 | fi
219 |
220 | # set env variables
221 | echo ${K8sClusterName} > /opt/kops-state/KOPS_CLUSTER_NAME
222 | echo "INIT KOPS with: K8sClusterName: ${K8sClusterName}"
223 |
224 | echo "export KOPS_STATE_STORE=${KOPS_STATE_STORE}" >> /etc/bashrc
225 | echo "export NAME=${K8sClusterName}" >> /etc/bashrc
226 |
227 | echo "export KOPS_STATE_STORE=${KOPS_STATE_STORE}" >> /home/ubuntu/.bashrc
228 | echo "export NAME=${K8sClusterName}" >> /home/ubuntu/.bashrc
229 |
230 | echo "export KOPS_STATE_STORE=${KOPS_STATE_STORE}" >> /root/.bashrc
231 | echo "export NAME=${K8sClusterName}" >> /root/.bashrc
232 |
233 |
234 | #tag instance
235 | instance_id=`curl http://169.254.169.254/latest/meta-data/instance-id`
236 | aws ec2 create-tags --resources ${instance_id} --tags Key=KOPS-state-store-bucket,Value=${KOPS_STATE_STORE} --region ${AWSRegion}
237 |
238 | #create kops config
239 | if [ "${Ec2K8sMultiAZMaster}" == "true" ];
240 | then
241 | kops create cluster \
242 | --name="${K8sClusterName}" \
243 | --cloud-labels="Name=${K8sClusterName}" \
244 | ${dns_zone} \
245 | ${dns} \
246 | ${node_zones} \
247 | ${master_zones} \
248 | --master-count=3 \
249 | --state="s3://${s3bucket}" \
250 | --topology="private" \
251 | --networking="calico" \
252 | --node-count="${Ec2K8sNodeCapacityMin}" \
253 | --node-size="${Ec2K8sNodeInstanceType}" \
254 | --master-size="${Ec2K8sMasterInstanceType}" \
255 | --vpc="${VPC}" \
256 | --cloud="aws" \
257 | --ssh-public-key="id_rsa.pub" \
258 | ${k8s_ami} \
259 | --associate-public-ip="false" \
260 | ${api_lb_type} \
261 | --network-cidr="${NetworkCIDR}" \
262 | --master-security-groups="${K8sMasterAndNodeSecurityGroup}" \
263 | --node-security-groups="${K8sMasterAndNodeSecurityGroup}" \
264 | --master-volume-size="${Ec2EBSK8sDiskSizeGb}" \
265 | --node-volume-size="${Ec2EBSK8sDiskSizeGb}" \
266 | --authorization="RBAC" \
267 | --dry-run \
268 | --output="yaml" > /opt/kops-config/${K8sClusterName}.yaml || exit 1
269 | else
270 | kops create cluster \
271 | --name="${K8sClusterName}" \
272 | --cloud-labels="Name=${K8sClusterName}" \
273 | ${dns_zone} \
274 | ${dns} \
275 | ${node_zones} \
276 | --master-count=1 \
277 | --state="s3://${s3bucket}" \
278 | --topology="private" \
279 | --networking="calico" \
280 | --node-count="${Ec2K8sNodeCapacityMin}" \
281 | --node-size="${Ec2K8sNodeInstanceType}" \
282 | --master-size="${Ec2K8sMasterInstanceType}" \
283 | --vpc="${VPC}" \
284 | --cloud="aws" \
285 | --ssh-public-key="id_rsa.pub" \
286 | ${k8s_ami} \
287 | --associate-public-ip="false" \
288 | ${api_lb_type} \
289 | --network-cidr="${NetworkCIDR}" \
290 | --master-security-groups="${K8sMasterAndNodeSecurityGroup}" \
291 | --node-security-groups="${K8sMasterAndNodeSecurityGroup}" \
292 | --master-volume-size="${Ec2EBSK8sDiskSizeGb}" \
293 | --node-volume-size="${Ec2EBSK8sDiskSizeGb}" \
294 | --authorization="RBAC" \
295 | --dry-run \
296 | --output="yaml" > /opt/kops-config/${K8sClusterName}.yaml || exit 1
297 | fi
298 |
299 | #apply subnet and policy mod
300 | python kops-sharedvpc-iam-yamlconfig.py ${AWSRegion} /opt/kops-config/${K8sClusterName}.yaml kops-cluster-additionalpolicies.json /opt/kops-config/${K8sClusterName}.MOD.yaml ${NODES_SPOT_PRICE} ${Ec2K8sNodeCapacityMax}
301 |
302 | #check existing modified config
303 | if [[ ! -e "/opt/kops-config/${K8sClusterName}.MOD.yaml" ]];
304 | then
305 | echo "ERROR: missing Kops config file!"
306 | exit 1
307 | fi
308 |
309 | #create k8s cluster config
310 | kops create -f /opt/kops-config/${K8sClusterName}.MOD.yaml
311 |
312 | #create k8s secret with Ubuntu SSH key
313 | kops create secret --name ${K8sClusterName} sshpublickey admin -i id_rsa.pub
314 |
315 | #apply cluster changes
316 | kops update cluster ${K8sClusterName} --yes
317 |
318 | #wait for cluster ready
319 | k8s_done=""
320 | k8s_successful=1
321 |
322 | #init kops environment on Bastion host
323 | export HOME=/opt
324 | cd $HOME
325 | kops export kubecfg ${K8sClusterName}
326 |
327 | mkdir -p /home/ubuntu/.kube
328 | cp $HOME/.kube/config /home/ubuntu/.kube/
329 |
330 | for i in {1..90};
331 | do
332 | clusterstate=`kops validate cluster | egrep -i "is not healthy|is ready" | grep -v grep`;
333 | if [[ -n ${clusterstate} ]];
334 | then
335 | echo ${clusterstate};
336 | k8s_done="OK";
337 | k8s_successful=0;
338 | break;
339 | else
340 | echo $i;
341 | sleep 10;
342 | fi
343 | done
344 |
345 | sleep 10
346 |
347 | #init kops environment on Bastion host
348 | export HOME=/opt
349 | cd $HOME
350 | kops export kubecfg ${K8sClusterName}
351 |
352 |
353 | mkdir -p /home/ubuntu/.kube
354 | cp $HOME/.kube/config /home/ubuntu/.kube/
355 |
356 | mkdir -p /root/.kube
357 | cp $HOME/.kube/config /root/.kube/
358 |
359 | chown -R ubuntu:ubuntu /home/ubuntu
360 | chown -R ubuntu:ubuntu /opt
361 | chmod -R og+rX /opt
362 |
363 | if [[ ! -n ${k8s_done} ]];
364 | then
365 | echo "########################"
366 | echo "ERROR CLUSTER DOES NOT RUNNING HEALTHY!"
367 | echo "########################"
368 | else
369 | echo "########################"
370 | echo "K8S CLUSTER IS RUNNING."
371 | echo "########################"
372 | fi
373 |
374 | ## workaround for RHEL/CentOS/Amazonlinux host + Calico + Multi-AZ nezworking / k8s-ec2-srcdst
375 | if [ "${Ec2K8sAMIOsType}" == "CentOS-7" ] || [ "${Ec2K8sAMIOsType}" == "RHEL-7" ] || [ "${Ec2K8sAMIOsType}" == "AmazonLinux2" ];
376 | then
377 | echo "APPLY k8s-ec2-srcdst pathch..."
378 | kubectl patch deployment k8s-ec2-srcdst --namespace kube-system -p '{"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{},"labels":{"k8s-app":"k8s-ec2-srcdst","role.kubernetes.io/networking":"1"},"name":"k8s-ec2-srcdst","namespace":"kube-system"},"spec":{"replicas":1,"selector":{"matchLabels":{"k8s-app":"k8s-ec2-srcdst"}},"template":{"metadata":{"annotations":{"scheduler.alpha.kubernetes.io/critical-pod":""},"labels":{"k8s-app":"k8s-ec2-srcdst","role.kubernetes.io/networking":"1"}},"spec":{"containers":[{"imagePullPolicy":"Always","name":"k8s-ec2-srcdst","resources":{"requests":{"cpu":"10m","memory":"64Mi"}},"volumeMounts":[{"mountPath":"/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt","name":"ssl-certs","readOnly":true}]}],"hostNetwork":true,"nodeSelector":{"node-role.kubernetes.io/master":""},"serviceAccountName":"k8s-ec2-srcdst","tolerations":[{"effect":"NoSchedule","key":"node-role.kubernetes.io/master"},{"key":"CriticalAddonsOnly","operator":"Exists"}],"volumes":[{"hostPath":{"path":"/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt"},"name":"ssl-certs"}]}}}}'
379 | fi
380 |
381 | #Enable legacy authorization mode
382 | kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --user=admin --user=kubelet --group=system:serviceaccounts
383 |
384 | for i in {1..120};
385 | do
386 | clusterstate=`kops validate cluster | grep -i "is ready" | grep -v grep`;
387 | if [[ -n ${clusterstate} ]];
388 | then
389 | echo ${clusterstate};
390 | k8s_done="OK";
391 | k8s_successful=0;
392 | break;
393 | else
394 | echo $i;
395 | sleep 10;
396 | fi
397 | done
398 |
399 |
400 | #######################
401 | # KOPS Addons
402 | #######################
403 | echo "########################"
404 | echo "Install addons ..."
405 | echo "########################"
406 |
407 | cd /opt/bastion-init/
408 |
409 | sleep 5
410 |
411 | # Kubernetes Cluster Autoscaler
412 | if [ "${KubernetesClusterAutoscaler}" == "true" ];
413 | then
414 | echo "Install K8s Cluster Autoscaler ..."
415 |
416 | #RH certpath: /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
417 |
418 | CLOUD_PROVIDER=aws
419 | IMAGE=gcr.io/google-containers/cluster-autoscaler:v1.3.5
420 | MIN_NODES=${Ec2K8sNodeCapacityMin}
421 | MAX_NODES=${Ec2K8sNodeCapacityMax}
422 | AWS_REGION=${AWSRegion}
423 | GROUP_NAME="nodes.${K8sClusterName}"
424 | SSL_CERT_PATH=${host_ssl_certpath}
425 |
426 | addon=cluster-autoscaler.yml
427 |
428 | sed -i -e "s@{{CLOUD_PROVIDER}}@${CLOUD_PROVIDER}@g" "${addon}"
429 | sed -i -e "s@{{IMAGE}}@${IMAGE}@g" "${addon}"
430 | sed -i -e "s@{{MIN_NODES}}@${MIN_NODES}@g" "${addon}"
431 | sed -i -e "s@{{MAX_NODES}}@${MAX_NODES}@g" "${addon}"
432 | sed -i -e "s@{{GROUP_NAME}}@${GROUP_NAME}@g" "${addon}"
433 | sed -i -e "s@{{AWS_REGION}}@${AWS_REGION}@g" "${addon}"
434 | sed -i -e "s@{{SSL_CERT_PATH}}@${SSL_CERT_PATH}@g" "${addon}"
435 |
436 | kubectl apply -f ${addon}
437 | fi
438 |
439 | # Kubernetes ALB ingress controller
440 | if [ "${KubernetesALBIngressController}" == "true" ];
441 | then
442 | echo "Install K8s ALB ingress controller ..."
443 |
444 | addon=alb-ingress-controller.yaml
445 | sed -i 's/__REPLACE_AWS_REGION__/'${AWSRegion}'/g' ${addon}
446 | sed -i 's/__REPLACE_K8S_CLUSTER_NAME__/'${K8sClusterName}'/g' ${addon}
447 | sed -i 's/__REPLACE_VPC_ID__/'${VPC}'/g' ${addon}
448 |
449 | kubectl apply -f ${addon}
450 | fi
451 |
452 |
453 | # kubernetes dashboard
454 | if [ "${KubernetesDashboard}" == "true" ];
455 | then
456 | echo "Install monitoring plugins ( influxDB, grafana, heapster ) ..."
457 | addon=kubernetes-monitoring.yaml
458 |
459 | SSL_CERT_DIR=${host_ssl_certdir}
460 | sed -i -e "s@{{SSL_CERT_DIR}}@${SSL_CERT_DIR}@g" "${addon}"
461 | kubectl apply -f ${addon}
462 |
463 | echo "Install Kubernetes Dashboard ..."
464 | kubectl apply -f kubernetes-dashboard.yaml
465 |
466 | fi
467 |
468 | # kubernetes external DNS plugin
469 | if [ "${KubernetesExternalDNSPlugin}" == "true" ];
470 | then
471 | echo "Install external-dns plugin ..."
472 | addon=alb-dns-external.yaml
473 |
474 | if [[ ! -n ${KubernetesExternalDNSName} ]];
475 | then
476 | KubernetesExternalDNSName=${K8sClusterName}
477 | fi
478 |
479 | sed -i 's/__REPLACE_DNS_NAME__/'${KubernetesExternalDNSName}'/g' ${addon}
480 | sed -i 's/__REPLACE_ZONE_TXT_ID__/'${KubernetesExternalDNSTXTSelector}'/g' ${addon}
481 | kubectl apply -f ${addon}
482 |
483 | fi
484 |
485 | #final kops validation
486 | for i in {1..120};
487 | do
488 | clusterstate=`kops validate cluster | grep "is ready" | grep -v grep`;
489 | if [[ -n ${clusterstate} ]];
490 | then
491 | echo ${clusterstate};
492 | k8s_done="OK";
493 | k8s_successful=0;
494 | break;
495 | else
496 | echo $i;
497 | sleep 10;
498 | fi
499 | done
500 |
501 | for _ in {1..180};
502 | do
503 | daskstatus=`kubectl get pods --all-namespaces | grep "ContainerCreating"`
504 | if [[ -n ${daskstatus} ]];
505 | then
506 | echo "Waiting UP ALL CONTAINERS ...";
507 | sleep 10;
508 | continue;
509 | else
510 | echo "Kubernetes IS UP!"
511 | break;
512 | fi
513 | done
514 |
515 | echo "Kubernetes clutser is running."
516 |
517 | echo "########################"
518 | echo "DONE INIT-KOPS. EXIT ${k8s_successful}"
519 | echo "########################"
520 | exit ${k8s_successful}
521 |
--------------------------------------------------------------------------------
/bootstrap/05-init-kubernetes-dashboard.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | KubernetesDashboardUsername=${1}
4 | KubernetesDashboardPassword=${2}
5 |
6 | echo "#################"
7 | echo "START INIT-DASHBOARD."
8 |
9 | su ubuntu -c "nohup kubectl proxy > /dev/null 2>&1 &"
10 |
11 | echo "*/5 * * * * ubuntu nohup kubectl proxy > /dev/null 2>&1 &" | tee --append /etc/crontab
12 |
13 | apt-get -y install apache2 fail2ban
14 |
15 | a2enmod proxy
16 | a2enmod proxy_http
17 | a2enmod headers
18 | a2enmod rewrite
19 |
20 | service apache2 restart
21 |
22 | echo "${KubernetesDashboardPassword}" | htpasswd -i -c /opt/htpasswd-dashboard ${KubernetesDashboardUsername}
23 |
24 | cat <<'EOF' > /etc/apache2/sites-available/000-default.conf
25 |
26 | ServerAdmin webmaster@localhost
27 | DocumentRoot /var/www
28 | ProxyRequests Off
29 | ProxyPreserveHost Off
30 |
31 | AllowEncodedSlashes NoDecode
32 |
33 |
34 | AuthType Basic
35 | AuthName "Kubernetes Dashboard"
36 | AuthBasicProvider file
37 | AuthUserFile "/opt/htpasswd-dashboard"
38 | Require valid-user
39 |
40 |
41 | RequestHeader unset Authorization
42 |
43 | Redirect "/ui" /api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/overview?namespace=_all
44 | ProxyPass /ui !
45 |
46 | ProxyPass / http://127.0.0.1:8001/ nocanon
47 | ProxyPassReverse / http://127.0.0.1:8001/
48 | CustomLog ${APACHE_LOG_DIR}/access.log combined
49 |
50 | EOF
51 |
52 | service apache2 restart
53 |
54 | TOKEN=`su ubuntu -c 'kubectl get secret $(kubectl get serviceaccount kubernetes-dashboard -n kube-system -o jsonpath="{.secrets[0].name}") -n kube-system -o jsonpath="{.data.token}"' | base64 --decode`
55 |
56 | echo ${TOKEN} > /opt/kubernetes-dashboard-auth-token
57 |
58 | echo "########################"
59 | echo "DONE INIT-DASHBOARD. EXIT 0"
60 | echo "########################"
61 | exit 0
62 |
--------------------------------------------------------------------------------
/bootstrap/alb-dns-external.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: external-dns
5 | ---
6 | apiVersion: rbac.authorization.k8s.io/v1beta1
7 | kind: ClusterRole
8 | metadata:
9 | name: external-dns
10 | rules:
11 | - apiGroups: [""]
12 | resources: ["services"]
13 | verbs: ["get","watch","list"]
14 | - apiGroups: [""]
15 | resources: ["pods"]
16 | verbs: ["get","watch","list"]
17 | - apiGroups: ["extensions"]
18 | resources: ["ingresses"]
19 | verbs: ["get","watch","list"]
20 | - apiGroups: [""]
21 | resources: ["nodes"]
22 | verbs: ["list"]
23 | ---
24 | apiVersion: rbac.authorization.k8s.io/v1beta1
25 | kind: ClusterRoleBinding
26 | metadata:
27 | name: external-dns-viewer
28 | roleRef:
29 | apiGroup: rbac.authorization.k8s.io
30 | kind: ClusterRole
31 | name: external-dns
32 | subjects:
33 | - kind: ServiceAccount
34 | name: external-dns
35 | namespace: default
36 | ---
37 | apiVersion: extensions/v1beta1
38 | kind: Deployment
39 | metadata:
40 | name: external-dns
41 | spec:
42 | strategy:
43 | type: Recreate
44 | template:
45 | metadata:
46 | labels:
47 | app: external-dns
48 | spec:
49 | serviceAccountName: external-dns
50 | containers:
51 | - name: external-dns
52 | image: registry.opensource.zalan.do/teapot/external-dns:latest
53 | args:
54 | - --source=service
55 | - --source=ingress
56 | - --domain-filter=__REPLACE_DNS_NAME__
57 | - --provider=aws
58 | - --policy=sync
59 | - --registry=txt
60 | - --txt-owner-id=__REPLACE_ZONE_TXT_ID__
61 |
--------------------------------------------------------------------------------
/bootstrap/alb-ingress-301-redirection-example.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Ingress
3 | metadata:
4 | annotations:
5 | alb.ingress.kubernetes.io/actions.redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "StatusCode": "HTTP_301", "Port": "443"}}'
6 | alb.ingress.kubernetes.io/certificate-arn: arn:*****
7 | alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80, "HTTPS": 443}]'
8 | alb.ingress.kubernetes.io/scheme: internet-facing
9 | alb.ingress.kubernetes.io/security-groups: sg-*******
10 | alb.ingress.kubernetes.io/successCodes: 200,301,302,303,401,403,404,405
11 | labels:
12 | run: aws-elb-test-ingress
13 | name: aws-elb-test-ingress
14 | spec:
15 | rules:
16 | - http:
17 | paths:
18 | - backend:
19 | serviceName: redirect
20 | servicePort: use-annotation
21 | path: /*
22 | - host: kubermetes-service.example.com
23 | http:
24 | paths:
25 | - backend:
26 | serviceName: kubermetes-service-1-name
27 | servicePort: 80
28 | path: /*
29 | - host: kubermetes-service-2.example.com
30 | http:
31 | paths:
32 | - backend:
33 | serviceName: kubermetes-service-2-name
34 | servicePort: 80
35 | path: /*
36 |
--------------------------------------------------------------------------------
/bootstrap/alb-ingress-controller.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: rbac.authorization.k8s.io/v1
3 | kind: ClusterRole
4 | metadata:
5 | labels:
6 | app.kubernetes.io/name: alb-ingress-controller
7 | name: alb-ingress-controller
8 | rules:
9 | - apiGroups:
10 | - ""
11 | - extensions
12 | resources:
13 | - configmaps
14 | - endpoints
15 | - events
16 | - ingresses
17 | - ingresses/status
18 | - services
19 | verbs:
20 | - create
21 | - get
22 | - list
23 | - update
24 | - watch
25 | - patch
26 | - apiGroups:
27 | - ""
28 | - extensions
29 | resources:
30 | - nodes
31 | - pods
32 | - secrets
33 | - services
34 | - namespaces
35 | verbs:
36 | - get
37 | - list
38 | - watch
39 | ---
40 | apiVersion: rbac.authorization.k8s.io/v1
41 | kind: ClusterRoleBinding
42 | metadata:
43 | labels:
44 | app.kubernetes.io/name: alb-ingress-controller
45 | name: alb-ingress-controller
46 | roleRef:
47 | apiGroup: rbac.authorization.k8s.io
48 | kind: ClusterRole
49 | name: alb-ingress-controller
50 | subjects:
51 | - kind: ServiceAccount
52 | name: alb-ingress-controller
53 | namespace: kube-system
54 | ---
55 | apiVersion: v1
56 | kind: ServiceAccount
57 | metadata:
58 | labels:
59 | app.kubernetes.io/name: alb-ingress-controller
60 | name: alb-ingress-controller
61 | namespace: kube-system
62 | ---
63 |
64 | # Application Load Balancer (ALB) Ingress Controller Deployment Manifest.
65 | # This manifest details sensible defaults for deploying an ALB Ingress Controller.
66 | # GitHub: https://github.com/kubernetes-sigs/aws-alb-ingress-controller
67 | apiVersion: apps/v1
68 | kind: Deployment
69 | metadata:
70 | labels:
71 | app.kubernetes.io/name: alb-ingress-controller
72 | name: alb-ingress-controller
73 | # Namespace the ALB Ingress Controller should run in. Does not impact which
74 | # namespaces it's able to resolve ingress resource for. For limiting ingress
75 | # namespace scope, see --watch-namespace.
76 | namespace: kube-system
77 | spec:
78 | selector:
79 | matchLabels:
80 | app.kubernetes.io/name: alb-ingress-controller
81 | template:
82 | metadata:
83 | labels:
84 | app.kubernetes.io/name: alb-ingress-controller
85 | spec:
86 | containers:
87 | - name: alb-ingress-controller
88 | args:
89 | # Limit the namespace where this ALB Ingress Controller deployment will
90 | # resolve ingress resources. If left commented, all namespaces are used.
91 | # - --watch-namespace=your-k8s-namespace
92 |
93 | # Setting the ingress-class flag below ensures that only ingress resources with the
94 | # annotation kubernetes.io/ingress.class: "alb" are respected by the controller. You may
95 | # choose any class you'd like for this controller to respect.
96 | - --ingress-class=alb
97 |
98 | # REQUIRED
99 | # Name of your cluster. Used when naming resources created
100 | # by the ALB Ingress Controller, providing distinction between
101 | # clusters.
102 | - --cluster-name=__REPLACE_K8S_CLUSTER_NAME__
103 |
104 | # AWS VPC ID this ingress controller will use to create AWS resources.
105 | # If unspecified, it will be discovered from ec2metadata.
106 | - --aws-vpc-id=__REPLACE_VPC_ID__
107 |
108 | # AWS region this ingress controller will operate in.
109 | # If unspecified, it will be discovered from ec2metadata.
110 | # List of regions: http://docs.aws.amazon.com/general/latest/gr/rande.html#vpc_region
111 | - --aws-region=__REPLACE_AWS_REGION__
112 |
113 | # Enables logging on all outbound requests sent to the AWS API.
114 | # If logging is desired, set to true.
115 | # - ---aws-api-debug
116 | # Maximum number of times to retry the aws calls.
117 | # defaults to 10.
118 | # - --aws-max-retries=10
119 | #env:
120 | # AWS key id for authenticating with the AWS API.
121 | # This is only here for examples. It's recommended you instead use
122 | # a project like kube2iam for granting access.
123 | # - name: AWS_REGION
124 | # value: __REPLACE_AWS_REGION__
125 |
126 | # AWS key secret for authenticating with the AWS API.
127 | # This is only here for examples. It's recommended you instead use
128 | # a project like kube2iam for granting access.
129 | #- name: AWS_SECRET_ACCESS_KEY
130 | # value: SECRETVALUE
131 | # Repository location of the ALB Ingress Controller.
132 | image: docker.io/amazon/aws-alb-ingress-controller:v1.1.2
133 | imagePullPolicy: Always
134 | serviceAccountName: alb-ingress-controller
135 | ---
136 |
137 |
--------------------------------------------------------------------------------
/bootstrap/apache2-dashboard-init-with-http-redirect.conf:
--------------------------------------------------------------------------------
1 |
2 | ServerAdmin webmaster@localhost
3 | DocumentRoot /var/www
4 |
5 | RewriteEngine On
6 | RewriteCond %{HTTPS} off
7 | RewriteRule (.*) https://%{SERVER_NAME}/$1 [R,L]
8 |
9 |
10 |
11 |
12 | ServerAdmin webmaster@localhost
13 | DocumentRoot /var/www
14 | ProxyRequests Off
15 | ProxyPreserveHost Off
16 |
17 | AllowEncodedSlashes NoDecode
18 |
19 |
20 | AuthType Basic
21 | AuthName "Kubernetes Dashboard"
22 | AuthBasicProvider file
23 | AuthUserFile "/opt/htpasswd-dashboard"
24 | Require valid-user
25 |
26 |
27 | RequestHeader unset Authorization
28 |
29 | Redirect "/ui" /api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/overview?namespace=_all
30 |
31 | ProxyPass /ui !
32 | ProxyPass / http://127.0.0.1:8001/ nocanon
33 | ProxyPassReverse / http://127.0.0.1:8001/
34 |
35 | CustomLog ${APACHE_LOG_DIR}/access.log combined
36 |
37 |
--------------------------------------------------------------------------------
/bootstrap/banner_message.txt:
--------------------------------------------------------------------------------
1 | #######################################################
2 | # _ __ _ _ #
3 | # | |/ / | | | | #
4 | # | ' /_ _| |__ ___ _ __ _ __ ___| |_ ___ ___ #
5 | # | <| | | | '_ \ / _ \ '__| '_ \ / _ \ __/ _ \/ __| #
6 | # | . \ |_| | |_) | __/ | | | | | __/ || __/\__ \ #
7 | # |_|\_\__,_|_.__/ \___|_| |_| |_|\___|\__\___||___/ #
8 | # | _ \ | | (_) #
9 | # | |_) | __ _ ___| |_ _ ___ _ __ #
10 | # | _ < / _` / __| __| |/ _ \| '_ \ #
11 | # | |_) | (_| \__ \ |_| | (_) | | | | #
12 | # |____/ \__,_|___/\__|_|\___/|_| |_| #
13 | #######################################################
14 |
--------------------------------------------------------------------------------
/bootstrap/bastion-bootstrap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 | # Kubernetes Bastion Bootstrapping
3 |
4 | # Configuration
5 | PROGRAM='Kubernetes Bastion'
6 |
7 | ##################################### Functions Definitions
8 | function checkos () {
9 | echo "${FUNCNAME[0]} Started ..."
10 | platform='unknown'
11 | unamestr=`uname`
12 | if [[ "$unamestr" == 'Linux' ]]; then
13 | platform='linux'
14 | else
15 | echo "[WARNING] This script is not supported on MacOS or freebsd"
16 | exit 1
17 | fi
18 | echo "${FUNCNAME[0]} Ended"
19 | }
20 |
21 | function usage () {
22 | echo "$0 "
23 | echo " "
24 | echo "options:"
25 | echo -e "--help \t Show options for this script"
26 | echo -e "--banner \t Enable or Disable Bastion Message"
27 | echo -e "--enable \t SSH Banner"
28 | echo -e "--tcp-forwarding \t Enable or Disable TCP Forwarding"
29 | echo -e "--x11-forwarding \t Enable or Disable X11 Forwarding"
30 | }
31 |
32 | function chkstatus () {
33 | echo "${FUNCNAME[0]} Started ..."
34 | if [ $? -eq 0 ]
35 | then
36 | echo "Script [PASS]"
37 | else
38 | echo "Script [FAILED]" >&2
39 | exit 1
40 | fi
41 | }
42 |
43 | function osrelease () {
44 | echo "${FUNCNAME[0]} Started ..."
45 | OS=`cat /etc/os-release | grep '^NAME=' | tr -d \" | sed 's/\n//g' | sed 's/NAME=//g'`
46 | if [ "$OS" == "Ubuntu" ]; then
47 | echo "Ubuntu"
48 | elif [ "$OS" == "Amazon Linux AMI" ]; then
49 | echo "AMZN"
50 | elif [ "$OS" == "CentOS Linux" ]; then
51 | echo "CentOS"
52 | else
53 | echo "Operating System Not Found"
54 | fi
55 | echo "${FUNCNAME[0]} Ended" >> /var/log/cfn-init.log
56 | }
57 |
58 |
59 | function request_eip() {
60 | echo "${FUNCNAME[0]} Started ..."
61 | release=$(osrelease)
62 | export Region=`curl http://169.254.169.254/latest/meta-data/placement/availability-zone | rev | cut -c 2- | rev`
63 |
64 | #Check if EIP already assigned.
65 | ALLOC=1
66 | ZERO=0
67 | INSTANCE_IP=`ifconfig -a | grep inet | awk {'print $2'} | sed 's/addr://g' | head -1`
68 | ASSIGNED=$(aws ec2 describe-addresses --region $Region --output text | grep $INSTANCE_IP | wc -l)
69 | if [ "$ASSIGNED" -gt "$ZERO" ]; then
70 | echo "Already assigned an EIP."
71 | else
72 | aws ec2 describe-addresses --region $Region --output text > /query.txt
73 | #Ensure we are only using EIPs from our Stack
74 | line=`curl http://169.254.169.254/latest/user-data/ | grep EIP_LIST`
75 | IFS=$':' DIRS=(${line//$','/:}) # Replace tabs with colons.
76 |
77 | for (( i=0 ; i<${#DIRS[@]} ; i++ )); do
78 | EIP=`echo ${DIRS[i]} | sed 's/\"//g' | sed 's/EIP_LIST=//g'`
79 | if [ $EIP != "Null" ]; then
80 | #echo "$i: $EIP"
81 | grep "$EIP" /query.txt >> /query2.txt;
82 | fi
83 | done
84 | mv /query2.txt /query.txt
85 |
86 |
87 | AVAILABLE_EIPs=`cat /query.txt | wc -l`
88 |
89 | if [ "$AVAILABLE_EIPs" -gt "$ZERO" ]; then
90 | FIELD_COUNT="5"
91 | INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
92 | echo "Running associate_eip_now"
93 | while read name;
94 | do
95 | #EIP_ENTRY=$(echo $name | grep eip | wc -l)
96 | EIP_ENTRY=$(echo $name | grep eni | wc -l)
97 | echo "EIP: $EIP_ENTRY"
98 | if [ "$EIP_ENTRY" -eq 1 ]; then
99 | echo "Already associated with an instance"
100 | echo ""
101 | else
102 | export EIP=`echo "$name" | sed 's/[\s]+/,/g' | awk {'print $4'}`
103 | EIPALLOC=`echo $name | awk {'print $2'}`
104 | echo "NAME: $name"
105 | echo "EIP: $EIP"
106 | echo "EIPALLOC: $EIPALLOC"
107 | aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $EIPALLOC --region $Region
108 | fi
109 | done < /query.txt
110 | else
111 | echo "[ERROR] No Elastic IPs available in this region"
112 | exit 1
113 | fi
114 |
115 | INSTANCE_IP=`ifconfig -a | grep inet | awk {'print $2'} | sed 's/addr://g' | head -1`
116 | ASSIGNED=$(aws ec2 describe-addresses --region $Region --output text | grep $INSTANCE_IP | wc -l)
117 | if [ "$ASSIGNED" -eq 1 ]; then
118 | echo "EIP successfully assigned."
119 | else
120 | #Retry
121 | while [ "$ASSIGNED" -eq "$ZERO" ]
122 | do
123 | sleep 3
124 | request_eip
125 | INSTANCE_IP=`ifconfig -a | grep inet | awk {'print $2'} | sed 's/addr://g' | head -1`
126 | ASSIGNED=$(aws ec2 describe-addresses --region $Region --output text | grep $INSTANCE_IP | wc -l)
127 | done
128 | fi
129 | fi
130 |
131 | echo "${FUNCNAME[0]} Ended"
132 | }
133 |
134 | function call_request_eip() {
135 | echo "${FUNCNAME[0]} Started ..."
136 | Region=`curl http://169.254.169.254/latest/meta-data/placement/availability-zone | rev | cut -c 2- | rev`
137 | ZERO=0
138 | INSTANCE_IP=`ifconfig -a | grep inet | awk {'print $2'} | sed 's/addr://g' | head -1`
139 | ASSIGNED=$(aws ec2 describe-addresses --region $Region --output text | grep $INSTANCE_IP | wc -l)
140 | if [ "$ASSIGNED" -gt "$ZERO" ]; then
141 | echo "Already assigned an EIP."
142 | else
143 | WAIT=$(shuf -i 1-30 -n 1)
144 | echo "Waiting for $WAIT ..."
145 | sleep "$WAIT"
146 | request_eip
147 | fi
148 | echo "${FUNCNAME[0]} Ended"
149 | }
150 |
151 | function prevent_process_snooping() {
152 | echo "${FUNCNAME[0]} Started ..."
153 | # Prevent bastion host users from viewing processes owned by other users.
154 | mount -o remount,rw,hidepid=2 /proc
155 | awk '!/proc/' /etc/fstab > temp && mv temp /etc/fstab
156 | echo "proc /proc proc defaults,hidepid=2 0 0" >> /etc/fstab
157 | echo "${FUNCNAME[0]} Ended"
158 | }
159 |
160 | ##################################### End Function Definitions
161 |
162 | # Call checkos to ensure platform is Linux
163 | checkos
164 |
165 | ## set an initial value
166 | SSH_BANNER="LINUX BASTION"
167 |
168 | # Read the options from cli input
169 | TEMP=`getopt -o h: --long help,banner:,enable:,tcp-forwarding:,x11-forwarding: -n $0 -- "$@"`
170 | eval set -- "$TEMP"
171 |
172 |
173 | if [ $# == 1 ] ; then echo "No input provided! type ($0 --help) to see usage help" >&2 ; exit 1 ; fi
174 |
175 | # extract options and their arguments into variables.
176 | while true; do
177 | case "$1" in
178 | -h | --help)
179 | usage
180 | exit 1
181 | ;;
182 | --banner)
183 | BANNER_PATH="$2";
184 | shift 2
185 | ;;
186 | --enable)
187 | ENABLE="$2";
188 | shift 2
189 | ;;
190 | --tcp-forwarding)
191 | TCP_FORWARDING="$2";
192 | shift 2
193 | ;;
194 | --x11-forwarding)
195 | X11_FORWARDING="$2";
196 | shift 2
197 | ;;
198 | --)
199 | break
200 | ;;
201 | *)
202 | break
203 | ;;
204 | esac
205 | done
206 |
207 | # BANNER CONFIGURATION
208 | BANNER_FILE="/etc/ssh_banner"
209 | if [[ $ENABLE == "true" ]];then
210 | if [ -z ${BANNER_PATH} ];then
211 | echo "BANNER_PATH is null skipping ..."
212 | else
213 | echo "BANNER_PATH = ${BANNER_PATH}"
214 | echo "Creating Banner in ${BANNER_FILE}"
215 | if [ $BANNER_FILE ] ;then
216 | echo "[INFO] Installing banner ... "
217 | echo -e "\n Banner ${BANNER_FILE}" >>/etc/ssh/sshd_config
218 | else
219 | echo "[INFO] banner file is not accessible skipping ..."
220 | exit 1;
221 | fi
222 | fi
223 | else
224 | echo "Banner message is not enabled!"
225 | fi
226 |
227 | release=$(osrelease)
228 |
229 | prevent_process_snooping
230 |
231 | call_request_eip
232 |
233 | systemctl restart ssh sshd
234 |
235 | echo "Bootstrap complete."
236 |
237 | exit 0
238 |
--------------------------------------------------------------------------------
/bootstrap/cluster-autoscaler.yml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: ServiceAccount
4 | metadata:
5 | labels:
6 | k8s-addon: cluster-autoscaler.addons.k8s.io
7 | k8s-app: cluster-autoscaler
8 | name: cluster-autoscaler
9 | namespace: kube-system
10 | ---
11 | apiVersion: rbac.authorization.k8s.io/v1beta1
12 | kind: ClusterRole
13 | metadata:
14 | name: cluster-autoscaler
15 | labels:
16 | k8s-addon: cluster-autoscaler.addons.k8s.io
17 | k8s-app: cluster-autoscaler
18 | rules:
19 | - apiGroups: [""]
20 | resources: ["events","endpoints"]
21 | verbs: ["create", "patch"]
22 | - apiGroups: [""]
23 | resources: ["pods/eviction"]
24 | verbs: ["create"]
25 | - apiGroups: [""]
26 | resources: ["pods/status"]
27 | verbs: ["update"]
28 | - apiGroups: [""]
29 | resources: ["endpoints"]
30 | resourceNames: ["cluster-autoscaler"]
31 | verbs: ["get","update"]
32 | - apiGroups: [""]
33 | resources: ["nodes"]
34 | verbs: ["watch","list","get","update"]
35 | - apiGroups: [""]
36 | resources: ["pods","services","replicationcontrollers","persistentvolumeclaims","persistentvolumes"]
37 | verbs: ["watch","list","get"]
38 | - apiGroups: ["extensions"]
39 | resources: ["replicasets","daemonsets"]
40 | verbs: ["watch","list","get"]
41 | - apiGroups: ["policy"]
42 | resources: ["poddisruptionbudgets"]
43 | verbs: ["watch","list"]
44 | - apiGroups: ["apps"]
45 | resources: ["statefulsets"]
46 | verbs: ["watch","list","get"]
47 | - apiGroups: ["storage.k8s.io"]
48 | resources: ["storageclasses"]
49 | verbs: ["watch","list","get"]
50 |
51 | ---
52 | apiVersion: rbac.authorization.k8s.io/v1beta1
53 | kind: Role
54 | metadata:
55 | name: cluster-autoscaler
56 | namespace: kube-system
57 | labels:
58 | k8s-addon: cluster-autoscaler.addons.k8s.io
59 | k8s-app: cluster-autoscaler
60 | rules:
61 | - apiGroups: [""]
62 | resources: ["configmaps"]
63 | verbs: ["create"]
64 | - apiGroups: [""]
65 | resources: ["configmaps"]
66 | resourceNames: ["cluster-autoscaler-status"]
67 | verbs: ["delete","get","update"]
68 |
69 | ---
70 | apiVersion: rbac.authorization.k8s.io/v1beta1
71 | kind: ClusterRoleBinding
72 | metadata:
73 | name: cluster-autoscaler
74 | labels:
75 | k8s-addon: cluster-autoscaler.addons.k8s.io
76 | k8s-app: cluster-autoscaler
77 | roleRef:
78 | apiGroup: rbac.authorization.k8s.io
79 | kind: ClusterRole
80 | name: cluster-autoscaler
81 | subjects:
82 | - kind: ServiceAccount
83 | name: cluster-autoscaler
84 | namespace: kube-system
85 |
86 | ---
87 | apiVersion: rbac.authorization.k8s.io/v1beta1
88 | kind: RoleBinding
89 | metadata:
90 | name: cluster-autoscaler
91 | namespace: kube-system
92 | labels:
93 | k8s-addon: cluster-autoscaler.addons.k8s.io
94 | k8s-app: cluster-autoscaler
95 | roleRef:
96 | apiGroup: rbac.authorization.k8s.io
97 | kind: Role
98 | name: cluster-autoscaler
99 | subjects:
100 | - kind: ServiceAccount
101 | name: cluster-autoscaler
102 | namespace: kube-system
103 |
104 | ---
105 | apiVersion: apps/v1
106 | kind: Deployment
107 | metadata:
108 | name: cluster-autoscaler
109 | namespace: kube-system
110 | labels:
111 | app: cluster-autoscaler
112 | spec:
113 | replicas: 1
114 | selector:
115 | matchLabels:
116 | app: cluster-autoscaler
117 | template:
118 | metadata:
119 | labels:
120 | app: cluster-autoscaler
121 | spec:
122 | serviceAccountName: cluster-autoscaler
123 | tolerations:
124 | - effect: NoSchedule
125 | key: node-role.kubernetes.io/master
126 | nodeSelector:
127 | kubernetes.io/role: master
128 | containers:
129 | - image: {{IMAGE}}
130 | name: cluster-autoscaler
131 | resources:
132 | limits:
133 | cpu: 100m
134 | memory: 300Mi
135 | requests:
136 | cpu: 100m
137 | memory: 300Mi
138 | command:
139 | - ./cluster-autoscaler
140 | - --v=4
141 | - --stderrthreshold=info
142 | - --cloud-provider={{CLOUD_PROVIDER}}
143 | - --skip-nodes-with-local-storage=false
144 | - --nodes={{MIN_NODES}}:{{MAX_NODES}}:{{GROUP_NAME}}
145 | env:
146 | - name: AWS_REGION
147 | value: {{AWS_REGION}}
148 | volumeMounts:
149 | - name: ssl-certs
150 | mountPath: {{SSL_CERT_PATH}}
151 | readOnly: true
152 | imagePullPolicy: "Always"
153 | volumes:
154 | - name: ssl-certs
155 | hostPath:
156 | path: "{{SSL_CERT_PATH}}"
157 |
--------------------------------------------------------------------------------
/bootstrap/kops-cluster-additionalpolicies.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Effect": "Allow",
4 | "Action": [
5 | "acm:*"
6 | ],
7 | "Resource": "*"
8 | },
9 | {
10 | "Effect": "Allow",
11 | "Action": [
12 | "autoscaling:*"
13 | ],
14 | "Resource": "*"
15 | },
16 | {
17 | "Effect": "Allow",
18 | "Action": [
19 | "ec2:*"
20 | ],
21 | "Resource": "*"
22 | },
23 | {
24 | "Effect": "Allow",
25 | "Action": [
26 | "elasticloadbalancing:*"
27 | ],
28 | "Resource": "*"
29 | },
30 | {
31 | "Effect": "Allow",
32 | "Action": [
33 | "iam:CreateServiceLinkedRole",
34 | "iam:GetServerCertificate",
35 | "iam:ListServerCertificates"
36 | ],
37 | "Resource": "*"
38 | },
39 | {
40 | "Effect": "Allow",
41 | "Action": [
42 | "ecr:*"
43 | ],
44 | "Resource": [
45 | "*"
46 | ]
47 | },
48 | {
49 | "Effect": "Allow",
50 | "Action": [
51 | "logs:*"
52 | ],
53 | "Resource": [
54 | "*"
55 | ]
56 | },
57 | {
58 | "Effect": "Allow",
59 | "Action": [
60 | "route53:ChangeResourceRecordSets"
61 | ],
62 | "Resource": [
63 | "arn:aws:route53:::hostedzone/*"
64 | ]
65 | },
66 | {
67 | "Effect": "Allow",
68 | "Action": [
69 | "route53:ListHostedZones",
70 | "route53:ListResourceRecordSets"
71 | ],
72 | "Resource": [
73 | "*"
74 | ]
75 | },
76 | {
77 | "Effect": "Allow",
78 | "Action": [
79 | "s3:Get*",
80 | "s3:List*"
81 | ],
82 | "Resource": "*"
83 | },
84 | {
85 | "Effect": "Allow",
86 | "Action": [
87 | "waf-regional:GetWebACLForResource",
88 | "waf-regional:GetWebACL",
89 | "waf-regional:AssociateWebACL",
90 | "waf-regional:DisassociateWebACL"
91 | ],
92 | "Resource": "*"
93 | },
94 | {
95 | "Effect": "Allow",
96 | "Action": [
97 | "waf:GetWebACL",
98 | "waf:AssociateWebACL",
99 | "waf:DisassociateWebACL"
100 | ],
101 | "Resource": "*"
102 | },
103 | {
104 | "Effect": "Allow",
105 | "Action": [
106 | "kms:*"
107 | ],
108 | "Resource": "*"
109 | },
110 | {
111 | "Effect": "Allow",
112 | "Action": [
113 | "tag:GetResources",
114 | "tag:TagResources",
115 | "tag:AddResourceTags",
116 | "tag:RemoveResourceTags",
117 | "tag:TagResources",
118 | "tag:UntagResources"
119 | ],
120 | "Resource": "*"
121 | },
122 | {
123 | "Effect": "Allow",
124 | "Action": [
125 | "sns:Publish"
126 | ],
127 | "Resource": [
128 | "*"
129 | ]
130 | },
131 | {
132 | "Effect": "Allow",
133 | "Action": [
134 | "s3:*"
135 | ],
136 | "Resource": "*"
137 | },
138 | {
139 | "Effect": "Allow",
140 | "Action": [
141 | "ssm:*"
142 | ],
143 | "Resource": "*"
144 | },
145 | {
146 | "Effect": "Allow",
147 | "Action": [
148 | "ssmmessages:*"
149 | ],
150 | "Resource": "*"
151 | },
152 | {
153 | "Effect": "Allow",
154 | "Action": [
155 | "ec2messages:*"
156 | ],
157 | "Resource": "*"
158 | },
159 | {
160 | "Effect": "Allow",
161 | "Action": [
162 | "ds:CreateComputer",
163 | "ds:DescribeDirectories"
164 | ],
165 | "Resource": "*"
166 | },
167 | {
168 | "Effect": "Allow",
169 | "Action": [
170 | "cloudwatch:PutMetricData"
171 | ],
172 | "Resource": "*"
173 | }
174 | ]
175 |
--------------------------------------------------------------------------------
/bootstrap/kops-sharedvpc-iam-yamlconfig.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python2.7
2 |
3 | import boto3
4 | import yaml
5 | import sys
6 | import os
7 | import time
8 |
9 |
10 | print "START."
11 | print time.ctime()
12 |
13 |
14 | #defaults
15 | region="eu-west-1"
16 | kopsconf_input="demo.yaml"
17 | kopsconf_additinalpolicies="kops-cluster-additionalpolicies.json"
18 | kopsconf_output_file="out.yaml"
19 | docker_awslogs_group="K8s-Docker"
20 |
21 | #aws region
22 | try:
23 | region=sys.argv[1]
24 | except:
25 | print "define ARG1: region!"
26 | sys.exit(1)
27 |
28 | #generated kops input config
29 | try:
30 | kopsconf_input=sys.argv[2]
31 | except:
32 | print "define ARG2: kops input config!"
33 | sys.exit(1)
34 |
35 | #additional policies
36 | try:
37 | kopsconf_additinalpolicies=sys.argv[3]
38 | except:
39 | print "define ARG3: additional JSON policy files for master/nodes"
40 | sys.exit(1)
41 |
42 |
43 | #output kops config yaml file
44 | try:
45 | kopsconf_output_file=sys.argv[4]
46 | except:
47 | print "define ARG5: kops output config"
48 | sys.exit(1)
49 |
50 | #maxspotprice for nodes
51 | max_spot_price_for_node=0.0
52 | try:
53 | max_spot_price_for_node=sys.argv[5]
54 | except:
55 | print "define ARG6: max spot price, unless 0: on-demand"
56 | pass
57 |
58 | #nodes capacity max
59 | max_nodes_capacity=None
60 | try:
61 | max_nodes_capacity=sys.argv[6]
62 | except:
63 | print "define ARG7: max number of nodes, unless equals min=max"
64 | pass
65 |
66 | if not os.path.exists(kopsconf_input):
67 | print "Missing kiops config input file!"
68 | sys.exit(1)
69 |
70 | if not os.path.exists(kopsconf_additinalpolicies):
71 | print "Missing additonal policy file!"
72 | sys.exit(1)
73 |
74 | yl=None
75 |
76 | #[ {az-name: subnet_id} ... ]
77 | private_subnets={}
78 | public_subnets={}
79 |
80 | #subnet config to replace in kops config
81 | replace_subnets=[]
82 |
83 | with open(kopsconf_input,"r") as f:
84 | yl=yaml.safe_load_all(f.read())
85 |
86 | kops=list(yl)
87 | vpcid=kops[0].get("spec").get("networkID")
88 | ec2 = boto3.resource('ec2',region_name=region)
89 | ec2client = boto3.client('ec2',region_name=region)
90 | vpc = ec2.Vpc(vpcid)
91 | subnet_iterator = vpc.subnets.all()
92 |
93 | #determine private subnets by routes (NO igw in routes associated with subnet)
94 | for s in subnet_iterator:
95 | public=False
96 | sid=s.subnet_id
97 | az=s.availability_zone
98 | #print sid
99 | #print az
100 | response = ec2client.describe_route_tables(
101 | Filters=[
102 | {
103 | 'Name': 'association.subnet-id',
104 | 'Values': [
105 | sid
106 | ]
107 | }
108 | ]
109 | )
110 | rtb = response['RouteTables'][0]['Associations'][0]['RouteTableId']
111 | rotb = ec2.RouteTable(rtb)
112 | #print "Routes:"
113 | for r in rotb.routes:
114 | #print r.nat_gateway_id
115 | #print r.gateway_id
116 | if r.gateway_id:
117 | if r.gateway_id.startswith("igw-"):
118 | #print r.gateway_id
119 | #print "skip"
120 | public=True
121 | if public:
122 | public_subnets[az]=sid
123 | continue
124 | private_subnets[az]=sid
125 |
126 | print "Private subnets in VPC: ", vpcid
127 | print private_subnets
128 | print "Public subnets in VPC: ", vpcid
129 | print public_subnets
130 |
131 |
132 | #replace config cidr with id
133 | subnets = kops[0].get("spec").get('subnets')
134 | for subnet in subnets:
135 | if subnet.get('type') == "Utility":
136 | continue
137 | zone=subnet.get('zone')
138 | zname=subnet.get('name')
139 | ztype=subnet.get('type')
140 | newprivatezone={}
141 | if zone in private_subnets:
142 | newprivatezone['id']=private_subnets[zone]
143 | newprivatezone['zone']=zone
144 | newprivatezone['name']=zname
145 | newprivatezone['type']=ztype
146 | if newprivatezone:
147 | replace_subnets.append(newprivatezone)
148 |
149 | for zone,sid in public_subnets.iteritems():
150 | newpubliczone={}
151 | newpubliczone['id']=sid
152 | newpubliczone['zone']=zone
153 | newpubliczone['name']="utility-"+zone
154 | newpubliczone['type']='Utility'
155 | if newpubliczone:
156 | replace_subnets.append(newpubliczone)
157 |
158 |
159 | print "Set new subnet definitions ..."
160 | print replace_subnets
161 | kops[0]['spec']['subnets']=replace_subnets
162 |
163 | print "Add calico inter-AZ networking ..."
164 | kops[0]['spec']['networking'] = {"calico": {"crossSubnet":True}}
165 |
166 | print "Add swap accept in GENERAL config and enable Custom metric ..."
167 | kops[0]['spec']['kubelet'] = {"failSwapOn":False}
168 |
169 | print "Enable POD autoscaling ..."
170 | kops[0]['spec']['kubeAPIServer'] = {"runtimeConfig": {"autoscaling/v2beta1":"true"}}
171 |
172 | print "Enable Custom Metrics ..."
173 | kops[0]['spec']['kubeControllerManager'] = {"horizontalPodAutoscalerUseRestClients": True}
174 |
175 | # yaml content
176 | #########################
177 | """
178 | - content: |
179 | #!/bin/bash -xe
180 | echo "* * * * * root sed -i '0,/^$/ s/^$/exit 0/' /opt/kubernetes/helpers/docker-healthcheck" >> /etc/crontab
181 | name: docker-healthcheck.sh
182 | type: text/x-shellscript
183 | """
184 |
185 | ##########################
186 | # node configs
187 | ##########################
188 | #print "Add swap accept in MASTER config
189 | kops[1]['spec']['kubelet'] = {"failSwapOn":False}
190 | kops[1]['spec']['additionalUserData'] = [{'content': '#!/bin/bash -xe\ndd if=/dev/zero of=/swapfile count=8192 bs=1MiB\nchmod 600 /swapfile\nmkswap /swapfile\nswapon /swapfile\nsysctl vm.swappiness=10\nsysctl vm.vfs_cache_pressure=50\n', 'type': 'text/x-shellscript', 'name': 'swap.sh'},{'content': '#!/bin/bash -xe\napt-get update\napt-get -y install nfs-common\n', 'type': 'text/x-shellscript', 'name': 'nfs.sh'}]
191 |
192 |
193 | #print "Add swap accept in NODES config
194 | kops[2]['spec']['kubelet'] = {"failSwapOn":False}
195 | kops[2]['spec']['additionalUserData'] = [{'content': '#!/bin/bash -xe\ndd if=/dev/zero of=/swapfile count=8192 bs=1MiB\nmkswap /swapfile\nswapon /swapfile\nsysctl vm.swappiness=10\nsysctl vm.vfs_cache_pressure=50\n', 'type': 'text/x-shellscript', 'name': 'swap.sh'},{'content': '#!/bin/bash -xe\napt-get update\napt-get -y install nfs-common\n', 'type': 'text/x-shellscript', 'name': 'nfs.sh'}]
196 |
197 | kops[2]['spec']['nodeLabels']["beta.kubernetes.io/fluentd-ds-ready"]="true"
198 | ##########################
199 |
200 |
201 | if max_spot_price_for_node:
202 | print "Set MAX SPOT price for NODES: ",str(max_spot_price_for_node)
203 | try:
204 | max_spot_price_for_node=float(max_spot_price_for_node)
205 | if max_spot_price_for_node > 0.0:
206 | kops[2]['spec']['maxPrice']=str(max_spot_price_for_node)
207 | except Exception,e:
208 | print "SPOT ERROR:",str(e)
209 | pass
210 |
211 | #set maximum size for NODES
212 | if max_nodes_capacity:
213 | print "Set MAX ASG size for NODES: ",str(max_nodes_capacity)
214 | kops[2]['spec']['maxSize']=int(max_nodes_capacity)
215 |
216 | print "Apply new policies ..."
217 | if os.path.exists(kopsconf_additinalpolicies):
218 | print "Add policy file: ", kopsconf_additinalpolicies
219 | ap=""
220 | with open(kopsconf_additinalpolicies,"r") as f:
221 | ap=f.read()
222 | additionalpolicies = {'node': ap, 'master': ap}
223 | #print additionalpolicies
224 | kops[0]['spec']['additionalPolicies']=additionalpolicies
225 |
226 | out=yaml.safe_dump_all(kops, default_flow_style=False)
227 | print out
228 | with open(kopsconf_output_file,"w") as f:
229 | f.write(out)
230 |
231 | sys.exit(0)
232 |
--------------------------------------------------------------------------------
/bootstrap/kubernetes-dashboard.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2017 The Kubernetes Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # ------------------- Dashboard Secret ------------------- #
16 |
17 | apiVersion: v1
18 | kind: Secret
19 | metadata:
20 | labels:
21 | k8s-app: kubernetes-dashboard
22 | name: kubernetes-dashboard-certs
23 | namespace: kube-system
24 | type: Opaque
25 |
26 | ---
27 | # ------------------- Dashboard Service Account ------------------- #
28 |
29 | apiVersion: v1
30 | kind: ServiceAccount
31 | metadata:
32 | labels:
33 | k8s-app: kubernetes-dashboard
34 | name: kubernetes-dashboard
35 | namespace: kube-system
36 |
37 | ---
38 | # ------------------- Dashboard Role & Role Binding ------------------- #
39 |
40 | kind: Role
41 | apiVersion: rbac.authorization.k8s.io/v1
42 | metadata:
43 | name: kubernetes-dashboard-minimal
44 | namespace: kube-system
45 | rules:
46 | # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
47 | - apiGroups: [""]
48 | resources: ["secrets"]
49 | verbs: ["create"]
50 | # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
51 | - apiGroups: [""]
52 | resources: ["configmaps"]
53 | verbs: ["create"]
54 | # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
55 | - apiGroups: [""]
56 | resources: ["secrets"]
57 | resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
58 | verbs: ["get", "update", "delete"]
59 | # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
60 | - apiGroups: [""]
61 | resources: ["configmaps"]
62 | resourceNames: ["kubernetes-dashboard-settings"]
63 | verbs: ["get", "update"]
64 | # Allow Dashboard to get metrics from heapster.
65 | - apiGroups: [""]
66 | resources: ["services"]
67 | resourceNames: ["heapster"]
68 | verbs: ["proxy"]
69 | - apiGroups: [""]
70 | resources: ["services/proxy"]
71 | resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
72 | verbs: ["get"]
73 |
74 | ---
75 | apiVersion: rbac.authorization.k8s.io/v1
76 | kind: RoleBinding
77 | metadata:
78 | name: kubernetes-dashboard-minimal
79 | namespace: kube-system
80 | roleRef:
81 | apiGroup: rbac.authorization.k8s.io
82 | kind: Role
83 | name: kubernetes-dashboard-minimal
84 | subjects:
85 | - kind: ServiceAccount
86 | name: kubernetes-dashboard
87 | namespace: kube-system
88 |
89 | ---
90 | # ------------------- Dashboard Deployment ------------------- #
91 |
92 | kind: Deployment
93 | apiVersion: apps/v1beta2
94 | metadata:
95 | labels:
96 | k8s-app: kubernetes-dashboard
97 | name: kubernetes-dashboard
98 | namespace: kube-system
99 | spec:
100 | replicas: 1
101 | revisionHistoryLimit: 10
102 | selector:
103 | matchLabels:
104 | k8s-app: kubernetes-dashboard
105 | template:
106 | metadata:
107 | labels:
108 | k8s-app: kubernetes-dashboard
109 | spec:
110 | containers:
111 | - name: kubernetes-dashboard
112 | image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0
113 | ports:
114 | - containerPort: 8443
115 | protocol: TCP
116 | args:
117 | - --auto-generate-certificates
118 | # Uncomment the following line to manually specify Kubernetes API server Host
119 | # If not specified, Dashboard will attempt to auto discover the API server and connect
120 | # to it. Uncomment only if the default does not work.
121 | # - --apiserver-host=http://my-address:port
122 | volumeMounts:
123 | - name: kubernetes-dashboard-certs
124 | mountPath: /certs
125 | # Create on-disk volume to store exec logs
126 | - mountPath: /tmp
127 | name: tmp-volume
128 | livenessProbe:
129 | httpGet:
130 | scheme: HTTPS
131 | path: /
132 | port: 8443
133 | initialDelaySeconds: 30
134 | timeoutSeconds: 30
135 | volumes:
136 | - name: kubernetes-dashboard-certs
137 | secret:
138 | secretName: kubernetes-dashboard-certs
139 | - name: tmp-volume
140 | emptyDir: {}
141 | serviceAccountName: kubernetes-dashboard
142 | # Comment the following tolerations if Dashboard must not be deployed on master
143 | tolerations:
144 | - key: node-role.kubernetes.io/master
145 | effect: NoSchedule
146 |
147 | ---
148 | # ------------------- Dashboard Service ------------------- #
149 |
150 | kind: Service
151 | apiVersion: v1
152 | metadata:
153 | labels:
154 | k8s-app: kubernetes-dashboard
155 | name: kubernetes-dashboard
156 | namespace: kube-system
157 | spec:
158 | ports:
159 | - port: 443
160 | targetPort: 8443
161 | selector:
162 | k8s-app: kubernetes-dashboard
163 |
--------------------------------------------------------------------------------
/bootstrap/kubernetes-monitoring.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: ClusterRoleBinding
3 | apiVersion: rbac.authorization.k8s.io/v1beta1
4 | metadata:
5 | name: heapster
6 | roleRef:
7 | apiGroup: rbac.authorization.k8s.io
8 | kind: ClusterRole
9 | name: system:heapster
10 | subjects:
11 | - kind: ServiceAccount
12 | name: heapster
13 | namespace: kube-system
14 | ---
15 | apiVersion: extensions/v1beta1
16 | kind: Deployment
17 | metadata:
18 | name: monitoring-influxdb
19 | namespace: kube-system
20 | spec:
21 | replicas: 1
22 | template:
23 | metadata:
24 | labels:
25 | task: monitoring
26 | k8s-app: influxdb
27 | spec:
28 | containers:
29 | - name: influxdb
30 | image: k8s.gcr.io/heapster-influxdb-amd64:v1.5.2
31 | volumeMounts:
32 | - mountPath: /data
33 | name: influxdb-storage
34 | volumes:
35 | - name: influxdb-storage
36 | emptyDir: {}
37 | ---
38 | apiVersion: v1
39 | kind: Service
40 | metadata:
41 | labels:
42 | task: monitoring
43 | # For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
44 | # If you are NOT using this as an addon, you should comment out this line.
45 | kubernetes.io/cluster-service: 'true'
46 | kubernetes.io/name: monitoring-influxdb
47 | name: monitoring-influxdb
48 | namespace: kube-system
49 | spec:
50 | ports:
51 | - port: 8086
52 | targetPort: 8086
53 | selector:
54 | k8s-app: influxdb
55 | ---
56 | apiVersion: extensions/v1beta1
57 | kind: Deployment
58 | metadata:
59 | name: monitoring-grafana
60 | namespace: kube-system
61 | spec:
62 | replicas: 1
63 | template:
64 | metadata:
65 | labels:
66 | task: monitoring
67 | k8s-app: grafana
68 | spec:
69 | containers:
70 | - name: grafana
71 | image: k8s.gcr.io/heapster-grafana-amd64:v5.0.4
72 | ports:
73 | - containerPort: 3000
74 | protocol: TCP
75 | volumeMounts:
76 | - mountPath: /etc/ssl/certs
77 | name: ca-certificates
78 | readOnly: true
79 | - mountPath: /var
80 | name: grafana-storage
81 | env:
82 | - name: INFLUXDB_HOST
83 | value: monitoring-influxdb
84 | - name: GF_SERVER_HTTP_PORT
85 | value: "3000"
86 | # The following env variables are required to make Grafana accessible via
87 | # the kubernetes api-server proxy. On production clusters, we recommend
88 | # removing these env variables, setup auth for grafana, and expose the grafana
89 | # service using a LoadBalancer or a public IP.
90 | - name: GF_AUTH_BASIC_ENABLED
91 | value: "false"
92 | - name: GF_AUTH_ANONYMOUS_ENABLED
93 | value: "true"
94 | - name: GF_AUTH_ANONYMOUS_ORG_ROLE
95 | value: Admin
96 | - name: GF_SERVER_ROOT_URL
97 | # If you're only using the API Server proxy, set this value instead:
98 | # value: /api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
99 | value: /
100 | volumes:
101 | - name: ca-certificates
102 | hostPath:
103 | path: /etc/ssl/certs
104 | - name: grafana-storage
105 | emptyDir: {}
106 | ---
107 | apiVersion: v1
108 | kind: Service
109 | metadata:
110 | labels:
111 | # For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
112 | # If you are NOT using this as an addon, you should comment out this line.
113 | kubernetes.io/cluster-service: 'true'
114 | kubernetes.io/name: monitoring-grafana
115 | name: monitoring-grafana
116 | namespace: kube-system
117 | spec:
118 | # In a production setup, we recommend accessing Grafana through an external Loadbalancer
119 | # or through a public IP.
120 | # type: LoadBalancer
121 | # You could also use NodePort to expose the service at a randomly-generated port
122 | # type: NodePort
123 | ports:
124 | - port: 80
125 | targetPort: 3000
126 | selector:
127 | k8s-app: grafana
128 | ---
129 | apiVersion: v1
130 | kind: ServiceAccount
131 | metadata:
132 | name: heapster
133 | namespace: kube-system
134 | ---
135 | apiVersion: v1
136 | kind: ServiceAccount
137 | metadata:
138 | name: heapster
139 | namespace: kube-system
140 | ---
141 | apiVersion: extensions/v1beta1
142 | kind: Deployment
143 | metadata:
144 | name: heapster
145 | namespace: kube-system
146 | spec:
147 | replicas: 1
148 | template:
149 | metadata:
150 | labels:
151 | task: monitoring
152 | k8s-app: heapster
153 | spec:
154 | serviceAccountName: heapster
155 | containers:
156 | - name: heapster
157 | image: k8s.gcr.io/heapster-amd64:v1.5.4
158 | imagePullPolicy: IfNotPresent
159 | command:
160 | - /heapster
161 | - --source=kubernetes:https://kubernetes.default
162 | - --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086
163 | ---
164 | apiVersion: v1
165 | kind: Service
166 | metadata:
167 | labels:
168 | task: monitoring
169 | # For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
170 | # If you are NOT using this as an addon, you should comment out this line.
171 | kubernetes.io/cluster-service: 'true'
172 | kubernetes.io/name: Heapster
173 | name: heapster
174 | namespace: kube-system
175 | spec:
176 | ports:
177 | - port: 80
178 | targetPort: 8082
179 | selector:
180 | k8s-app: heapster
181 |
182 |
--------------------------------------------------------------------------------
/bootstrap/purge-s3-versioned-bucket.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python2.7
2 |
3 | import boto3
4 | import os
5 | import sys
6 | import time
7 |
8 | bucket=sys.argv[1]
9 | region=sys.argv[2]
10 |
11 | print "DELETE BUCKET: "+bucket
12 | print time.ctime()
13 |
14 | session = boto3.Session(region_name=region)
15 | s3 = session.resource(service_name='s3')
16 | bucket = s3.Bucket(bucket)
17 | bucket.object_versions.delete()
18 | bucket.delete()
19 |
20 | print time.ctime()
21 | print "DONE."
22 |
23 | sys.exit(0)
24 |
--------------------------------------------------------------------------------
/bootstrap/tear-down-cluster.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | AWSRegion=${1}
4 |
5 | echo "TEAR DOWN START..."
6 |
7 | export KOPS_STATE_STORE=`cat /opt/kops-state/KOPS_STATE_STORE`
8 | export KOPS_CLUSTER_NAME=`cat /opt/kops-state/KOPS_CLUSTER_NAME`
9 | export AWS_DEFAULT_REGION=${AWSRegion}
10 |
11 | VPC=`cat /opt/kops-state/KOPS_VPC`
12 |
13 | kops export kubecfg --name $KOPS_CLUSTER_NAME
14 |
15 | echo "Delete k8s ingresses ... "
16 | ingress=""
17 | #delete ingresses
18 | for i in `kubectl get ingress -o yaml | grep "name:" | grep -v hostname | awk '{print $2}'`;
19 | do
20 | echo "Delete ingress: $i...";
21 | kubectl delete ingress $i --force;
22 | ingress="YES"
23 | sleep 10
24 |
25 | for j in `aws elbv2 describe-target-groups --region ${AWSRegion} --output text | grep arn | grep TARGETGROUPS | awk '{print $10}'`;
26 | do
27 | echo "Target group: $j ...";
28 | for h in {0..20};
29 | do
30 | N=`aws elbv2 describe-tags --resource-arns $j --region ${AWSRegion} --output text | grep $i`;
31 | if [[ -n "${N}" ]];
32 | then
33 | echo "DELETE TARGET GROUP: ${j} ...";
34 | H=`aws elbv2 delete-target-group --target-group-arn $j --region ${AWSRegion}`
35 | if [[ ! -n $H ]];
36 | then
37 | echo "Target group deleted.";
38 | break
39 | else
40 | echo "Waiting to delete target group ${H} ..."
41 | sleep 5
42 | continue
43 | fi
44 | else
45 | break;
46 | fi
47 | done
48 | done
49 | done
50 |
51 | #wait for target group deletion, it is async wait to remove ALB target groups
52 | echo "Wait a bit ... "
53 | if [[ "${ingress}" == "YES" ]];
54 | then
55 | sleep 20
56 | fi
57 |
58 | #delete cluster
59 | echo "Delete cluster ... "
60 | kops delete cluster --name $KOPS_CLUSTER_NAME --yes
61 |
62 | #purge remaining alb SGs
63 | if [[ -n "${VPC}" ]];
64 | then
65 | echo "Remove ALB SGs from VPC: ${VPC} ..."
66 | for sg in `aws ec2 describe-security-groups --filters Name=vpc-id,Values=${VPC} Name=tag-key,Values=ManagedBy Name=tag-value,Values=alb-ingress --output text --region ${AWSRegion} | grep SECURITYGROUPS | awk '{print $3}'`;
67 | do
68 | echo "Delete SG: $sg ";
69 | aws ec2 delete-security-group --group-id $sg --region ${AWSRegion};
70 | done
71 | else
72 | echo "NO VPC!"
73 | fi
74 |
75 | #delete local r53 dns zone
76 | echo "Delete R53 ZONE ... "
77 | if [[ -e "/opt/kops-state/KOPS_R53_PRIVATE_HOSTED_ZONE_ID" ]];
78 | then
79 | R53ZID=`cat /opt/kops-state/KOPS_R53_PRIVATE_HOSTED_ZONE_ID`
80 | if [[ -n ${R53ZID} ]];
81 | then
82 | aws route53 delete-hosted-zone --id ${R53ZID} --region ${AWSRegion}
83 | else
84 | echo "Missing R53 Zone ID!"
85 | fi
86 | fi
87 |
88 | #delete kops state bucket
89 | echo "Delete kops S3 state bucket ... "
90 | S3BUCKET=`cat /opt/kops-state/KOPS_STATE_STORE | cut -d '/' -f 3`
91 | python purge-s3-versioned-bucket.py ${S3BUCKET} ${AWSRegion}
92 |
93 | #delete log group
94 | echo "Delete AWS logs group ... "
95 | LOG2=`cat /opt/kops-state/KOPS_AWSLOGS`
96 | if [[ -n ${LOG2} ]];
97 | then
98 | aws logs delete-log-group --log-group-name ${LOG2} --region ${AWSRegion}
99 | fi
100 |
101 | echo "TEAR DOWN DONE. EXIT 0"
102 | exit 0
103 |
--------------------------------------------------------------------------------
/cfn-templates/latest-single-natinstance.yaml:
--------------------------------------------------------------------------------
1 | tc2-kuberntes-on-aws-v1.15.yaml
--------------------------------------------------------------------------------
/deploy-s3.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | aws s3 sync ./ s3://tc2-kubernetes/latest/ --profile=tc2-infra --exclude ".git/*" --exclude "$0" --delete
4 |
--------------------------------------------------------------------------------
/docs/TC2_Abstratct_production_grade_Kubernetes_deployment_on_AWS.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/totalcloudconsulting/kubernetes-aws/989cb3ec3b397c7d8b6ddb6ba9f9de1289132850/docs/TC2_Abstratct_production_grade_Kubernetes_deployment_on_AWS.pdf
--------------------------------------------------------------------------------
/docs/k8s-fullscale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/totalcloudconsulting/kubernetes-aws/989cb3ec3b397c7d8b6ddb6ba9f9de1289132850/docs/k8s-fullscale.png
--------------------------------------------------------------------------------
/docs/k8s-small-footprint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/totalcloudconsulting/kubernetes-aws/989cb3ec3b397c7d8b6ddb6ba9f9de1289132850/docs/k8s-small-footprint.png
--------------------------------------------------------------------------------
/easy-openvpn/README.md:
--------------------------------------------------------------------------------
1 | # easy-openvpn
2 |
3 | Based on easy-rsa. Added embed-key generation features. Create embed-style VPN certificates, keys, configs easily.
4 |
5 | __Purpose of the project__
6 |
7 | 1. Deploy OpenVPN setup on Ubuntu/Debian OS in 5 minutes, 3 easy steps.
8 | 2. Easy EMBED-style OpenVPN config generation which contains everything: key, cert, config in __ONE file__ !
9 | 3. AWS Cloudformation / automation ready (don't ask for anything)
10 |
11 | ----------
12 |
13 | # Prerequisites
14 |
15 | Ububtu / Debian OS (or based on) server
16 |
17 | __Install openvpn, git, zip__
18 |
19 | ```
20 | sudo apt-get install openvpn zip git
21 | ```
22 |
23 | __Clone__
24 |
25 | ```
26 | cd ~
27 | git clone https://github.com/tatobi/easy-openvpn.git
28 | ```
29 |
30 |
31 | # Create openvpn/keygen folder
32 |
33 | ```
34 | sudo mkdir -p /etc/openvpn/keygen
35 |
36 | ```
37 |
38 | __1. Copy content to the folder__
39 |
40 |
41 | ```
42 | sudo cp ~/easy-openvpn/keygen/* /etc/openvpn/keygen/
43 | ```
44 |
45 |
46 | __Edit "vars" file__
47 |
48 |
49 | ```
50 | sudo nano /etc/openvpn/keygen/vars
51 | ```
52 |
53 | Scroll dow to the end of file and set up the following variables:
54 |
55 | __!CHANGE SETTINGS HERE!__
56 |
57 | ```
58 | ############################################
59 | # Configure these fields
60 | ############################################
61 | export OPENVPN_CONF_DIR="/etc/openvpn"
62 | export OPENVPN_LOG_DIR="/var/log/openvpn"
63 | export KEY_SIZE=2048
64 | export CA_EXPIRE=7300
65 | export KEY_EXPIRE=7300
66 | export CRL_EXPIRE=7300
67 | export KEY_COUNTRY="CC"
68 | export KEY_PROVINCE="CHANGE_PROVINCE"
69 | export KEY_CITY="CHANGE_CITY"
70 | export KEY_ORG="CHANGE_ORG"
71 | export KEY_EMAIL="CHANGE_ORG_EMAIL"
72 | export KEY_OU="CHANGE_OU"
73 | export SERVER_ENDPOINT="CHANGE_SERVER_IP"
74 | export SERVER_PORT_TCP="443"
75 | export SERVER_PORT_UDP="1194"
76 |
77 | ```
78 |
79 | __2. Setup the server at TCP 443 (SSL) port__
80 |
81 |
82 | ```
83 | sudo su -
84 | cd /etc/openvpn/keygen
85 | ./create-server-tcp-gw
86 |
87 | START SERVER:
88 | service openvpn@server-tcp-gw start
89 | ```
90 |
91 | __3. Create embed style OpenVPN config/cert for client__
92 |
93 | ```
94 | sudo su -
95 | cd /etc/openvpn/keygen
96 | ./build-key-embed-commongw {cert.name.01}
97 |
98 | ```
99 |
100 | Download ZIPPED key to client, unzip to openvpn config folder and __thats all__!
101 | After proper setup at client, ALL traffic is going through your server securely.
102 |
103 | ----------
104 |
105 | # Revoke client cert
106 | ```
107 | sudo su -
108 | cd /etc/openvpn/keygen
109 | ./revoke-client {cert.name.01}
110 | ```
111 |
112 |
113 | # Using with PKCS12
114 |
115 | You can create PKCS12 (NOT embedded) certificates:
116 |
117 | ```
118 | sudo su -
119 | cd /etc/openvpn/keygen
120 | ./build-key-pkcs12-commongw {cert.name.01}
121 | ```
122 |
123 | ----------
124 |
125 | # Using UDP / gatewayless (site-to-site)
126 |
127 | Using through UDP means less overhead but maybe blocked by ISPs. It is better for S2S VPN.
128 |
129 | __Additonal routing setup is required!__
130 |
131 | Please read openvpn documentation how to edit ccd files and server routing.
132 |
133 | # Server
134 |
135 | ```
136 | sudo su -
137 | cd /etc/openvpn/keygen
138 | ./create-server
139 |
140 | (or already exist by previous setup):
141 | ./build-key-server
142 | ```
143 |
144 | # Keys
145 |
146 | ```
147 | sudo su -
148 | cd /etc/openvpn/keygen
149 |
150 |
151 | PKCS12:
152 | ./build-key-pkcs12 {cert.name.02}
153 |
154 | EMBED:
155 |
156 | ./build-key-embed {cert.name.02}
157 |
158 | NORMAL:
159 | ./build-key {cert.name.02}
160 |
161 | ```
162 |
163 | ----------
164 | # Purge
165 |
166 | # !!! WARNING clean-all deletes everything !!!
167 |
168 | ```
169 | sudo su -
170 | cd /etc/openvpn/keygen
171 | ./clean-all
172 | ```
173 |
174 | ----------
175 |
176 | Thank you for: easy-rsa project and jinnjo vgithub for pem-split.
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-ca:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Build a root certificate
5 | #
6 |
7 | source ./vars
8 |
9 | if [[ -e $KEY_DIR/ca.crt ]];
10 | then
11 | echo "WARNING: CA cert already exists! Exit."
12 | exit 1
13 | fi
14 |
15 |
16 | export EASY_RSA="${EASY_RSA:-.}"
17 | "$EASY_RSA/pkitool" --initca $*
18 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-crl-revoke:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ./vars
4 |
5 | CRL="crl.pem"
6 | RT="revoke-test.pem"
7 |
8 | if [ "$KEY_DIR" ]; then
9 | echo "Create revoke CRL ..."
10 | cd "$KEY_DIR"
11 | rm -f "$RT"
12 | chmod og+X $KEY_DIR
13 |
14 | # set defaults
15 | export KEY_CN=""
16 | export KEY_OU=""
17 |
18 | # generate a new CRL -- try to be compatible with
19 | # intermediate PKIs
20 | $OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG"
21 |
22 | #openssl ca -gencrl -keyfile keys/ca.key -cert keys/ca.crt -out keys/crl.pem -config ./openssl.cnf
23 |
24 | if [ -e export-ca.crt ]; then
25 | cat export-ca.crt "$CRL" >"$RT"
26 | else
27 | cat ca.crt "$CRL" >"$RT"
28 | fi
29 | echo "DONE"
30 | else
31 | echo 'Please source the vars script first (i.e. "source ./vars")'
32 | echo 'Make sure you have edited it to reflect your configuration.'
33 | fi
34 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-dh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Build Diffie-Hellman parameters for the server side
4 | # of an SSL/TLS connection.
5 |
6 | source ./vars
7 |
8 | if [[ -e $KEY_DIR/dh2048.pem ]];
9 | then
10 | echo "WARNING: dh2048.pem already exists! Exit."
11 | exit 1
12 | fi
13 |
14 |
15 | if [ -d $KEY_DIR ] && [ $KEY_SIZE ]; then
16 | $OPENSSL dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE}
17 | else
18 | echo 'Please source the vars script first (i.e. "source ./vars")'
19 | echo 'Make sure you have edited it to reflect your configuration.'
20 | fi
21 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-inter:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Make an intermediate CA certificate/private key pair using a locally generated
4 | # root certificate.
5 |
6 | source ./vars
7 |
8 | if [[ -e $KEY_DIR/ca.crt ]];
9 | then
10 | echo "WARNING:CA CERT already exists! Exit."
11 | exit 1
12 | fi
13 |
14 |
15 | export EASY_RSA="${EASY_RSA:-.}"
16 | "$EASY_RSA/pkitool" --inter $*
17 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-key:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Similar to build-key, but protect the private key
5 | # with a password and tar.gz keys into user dir
6 | #
7 |
8 | source ./vars
9 |
10 | if test $# -ne 1; then
11 | echo "usage: build-key ";
12 | exit 1
13 | fi
14 |
15 | if test $KEY_DIR; then
16 | cd $KEY_DIR && \
17 | export EASY_RSA="${EASY_RSA:-.}"
18 | "$EASY_RSA/pkitool" $*
19 | chmod 0600 $1.key && \
20 | mkdir $1 && \
21 | mv $1.* $1/ && \
22 | rm $1/*.csr && \
23 | cp ca.crt $1/ && \
24 | cp ta.key $1/$1.ta.key && \
25 | sed 's/CHANGE_KEY/'$1'/g' $OPENVPN_CONF_DIR/keygen/client-template.ovpn > $1/$1.ovpn && \
26 | sed -i 's/CHANGE_TA/'$1'/g' $1/$1.ovpn && \
27 | sed -i 's/CHANGE_SERVER/'$SERVER_ENDPOINT'/g' $1/$1.ovpn && \
28 | sed -i 's/CHANGE_PORT/'$SERVER_PORT_UDP'/g' $1/$1.ovpn && \
29 | cp $OPENVPN_CONF_DIR/keygen/ccd $OPENVPN_CONF_DIR/ccd/$1
30 | cd $1
31 | zip -r $1.zip ./*
32 | else
33 | echo "you must define KEY_DIR"
34 | fi
35 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-key-embed:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Similar to build-key, but protect the private key
5 | # with a password and tar.gz keys into user dir
6 | #
7 |
8 | source ./vars
9 |
10 | if test $# -ne 1; then
11 | echo "usage: build-key ";
12 | exit 1
13 | fi
14 |
15 | if test $KEY_DIR; then
16 | cd $KEY_DIR
17 | if [[ -e $1/$1.key && -d $1 ]];
18 | then
19 | echo "This key already exist. Try other name! Exit."
20 | exit 1
21 | fi
22 | export EASY_RSA="${EASY_RSA:-.}"
23 | "$EASY_RSA/pkitool" $*
24 | chmod 0600 $1.key && \
25 | mkdir $1 && \
26 | mv $1.* $1/ && \
27 | rm $1/*.csr && \
28 | cp $1/$1.crt c-tmp.crt && \
29 | $OPENVPN_CONF_DIR/keygen/pem-split c-tmp.crt && \
30 | $OPENVPN_CONF_DIR/keygen/pem-split ta.key && \
31 | cp $1/$1.key c-tmp.key && \
32 | cp ca.crt $1/ && \
33 | cp ta.key $1/$1.ta.key && \
34 | sed 's/CHANGE_SERVER/'$SERVER_ENDPOINT'/g' $OPENVPN_CONF_DIR/keygen/client-template-embed.ovpn > $1/$1.ovpn && \
35 | sed -i 's/CHANGE_PORT/'$SERVER_PORT_UDP'/g' $1/$1.ovpn && \
36 | perl -i -p0e 's/CHANGE_TA_KEY_BODY\n/`cat ta.key-0.key`/se' $1/$1.ovpn && \
37 | perl -i -p0e 's/CHANGE_CA_CRT_BODY\n/`cat ca.crt`/se' $1/$1.ovpn && \
38 | perl -i -p0e 's/CHANGE_CLIENT_CERT_BODY\n/`cat c-tmp.crt-0.crt`/se' $1/$1.ovpn && \
39 | perl -i -p0e 's/CHANGE_CLIENT_KEY_BODY\n/`cat c-tmp.key`/se' $1/$1.ovpn && \
40 | rm -f c-tmp.* && \
41 | cp $OPENVPN_CONF_DIR/keygen/ccd $OPENVPN_CONF_DIR/ccd/$1
42 | cd $1
43 | zip $1.zip ./$1.ovpn
44 | echo "########################"
45 | echo "DONE. DOWNLOAD EMBED KEY+CONF: $OPENVPN_CONF_DIR/keys/$1/$1.zip"
46 | else
47 | echo "you must define KEY_DIR"
48 | fi
49 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-key-embed-commongw:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Similar to build-key, but protect the private key
5 | # with a password and tar.gz keys into user dir
6 | #
7 |
8 | source ./vars
9 |
10 | if test $# -ne 1; then
11 | echo "usage: build-key ";
12 | exit 1
13 | fi
14 |
15 | if test $KEY_DIR; then
16 | cd $KEY_DIR
17 | if [[ -e $1/$1.key && -d $1 ]];
18 | then
19 | echo "This key already exist. Try other name! Exit."
20 | exit 1
21 | fi
22 | export EASY_RSA="${EASY_RSA:-.}"
23 | "$EASY_RSA/pkitool" $*
24 | chmod 0600 $1.key && \
25 | mkdir $1 && \
26 | mv $1.* $1/ && \
27 | rm $1/*.csr && \
28 | cp $1/$1.crt c-tmp.crt && \
29 | $OPENVPN_CONF_DIR/keygen/pem-split c-tmp.crt && \
30 | $OPENVPN_CONF_DIR/keygen/pem-split ta.key && \
31 | cp $1/$1.key c-tmp.key && \
32 | cp ca.crt $1/ && \
33 | cp ta.key $1/$1.ta.key && \
34 | sed 's/CHANGE_SERVER/'$SERVER_ENDPOINT'/g' $OPENVPN_CONF_DIR/keygen/client-template-embed-commongw.ovpn > $1/$1.ovpn && \
35 | sed -i 's/CHANGE_PORT/'$SERVER_PORT_TCP'/g' $1/$1.ovpn && \
36 | perl -i -p0e 's/CHANGE_TA_KEY_BODY\n/`cat ta.key-0.key`/se' $1/$1.ovpn && \
37 | perl -i -p0e 's/CHANGE_CA_CRT_BODY\n/`cat ca.crt`/se' $1/$1.ovpn && \
38 | perl -i -p0e 's/CHANGE_CLIENT_CERT_BODY\n/`cat c-tmp.crt-0.crt`/se' $1/$1.ovpn && \
39 | perl -i -p0e 's/CHANGE_CLIENT_KEY_BODY\n/`cat c-tmp.key`/se' $1/$1.ovpn && \
40 | rm -f c-tmp.* && \
41 | cp $OPENVPN_CONF_DIR/keygen/ccd $OPENVPN_CONF_DIR/ccd/$1
42 | cd $1
43 | zip $1.zip ./$1.ovpn
44 | echo "DONE. DOWNLOAD EMBED KEY+CONF: $OPENVPN_CONF_DIR/keys/$1/$1.zip"
45 | else
46 | echo "you must define KEY_DIR"
47 | fi
48 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-key-pkcs12:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Similar to build-key, but protect the private key
5 | # with a password and tar.gz keys into user dir
6 | #
7 |
8 | source ./vars
9 |
10 | if test $# -ne 1; then
11 | echo "usage: $0 ";
12 | exit 1
13 | fi
14 |
15 | if test $KEY_DIR; then
16 | cd $KEY_DIR
17 | if [[ -e $1/$1.key && -d $1 ]];
18 | then
19 | echo "This key already exist. Try other name! Exit."
20 | exit 1
21 | fi
22 | export EASY_RSA="${EASY_RSA:-.}"
23 | "$EASY_RSA/pkitool" --pkcs12 $*
24 | chmod 0600 $1.p12 && \
25 | mkdir $1 && \
26 | mv $1.* $1/ && \
27 | rm -f $1/*.csr && \
28 | cp ta.key $1/$1.ta.key && \
29 | sed 's/CHANGE_KEY/'$1'/g' $OPENVPN_CONF_DIR/keygen/client-template.p12.ovpn > $1/$1.ovpn && \
30 | sed -i 's/CHANGE_TA/'$1'/g' $1/$1.ovpn && \
31 | sed -i 's/CHANGE_SERVER/'$SERVER_ENDPOINT'/g' $1/$1.ovpn && \
32 | sed -i 's/CHANGE_PORT/'$SERVER_PORT_UDP'/g' $1/$1.ovpn && \
33 | cp $OPENVPN_CONF_DIR/keygen/ccd $OPENVPN_CONF_DIR/ccd/$1
34 | cd $1
35 | zip -r $1.zip ./*.ovpn ./*ta.key ./*.p12
36 | echo "DONE. KEY AND CONFIG:: $1.zip"
37 | else
38 | echo "you must define KEY_DIR..."
39 | fi
40 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-key-pkcs12-commongw:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Similar to build-key, but protect the private key
5 | # with a password and tar.gz keys into user dir
6 | #
7 |
8 | source ./vars
9 |
10 | if test $# -ne 1; then
11 | echo "usage: $0 ";
12 | exit 1
13 | fi
14 |
15 | if test $KEY_DIR; then
16 | cd $KEY_DIR
17 | if [[ -e $1/$1.key && -d $1 ]];
18 | then
19 | echo "This key already exist. Try other name! Exit."
20 | exit 1
21 | fi
22 | export EASY_RSA="${EASY_RSA:-.}"
23 | "$EASY_RSA/pkitool" --pkcs12 $*
24 | chmod 0600 $1.p12 && \
25 | mkdir $1 && \
26 | mv $1.* $1/ && \
27 | rm -f $1/*.csr && \
28 | cp ta.key $1/$1.ta.key && \
29 | sed 's/CHANGE_KEY/'$1'/g' $OPENVPN_CONF_DIR/keygen/client-template.commongw.p12.ovpn > $1/$1.ovpn && \
30 | sed -i 's/CHANGE_TA/'$1'/g' $1/$1.ovpn && \
31 | sed -i 's/CHANGE_SERVER/'$SERVER_ENDPOINT'/g' $1/$1.ovpn && \
32 | sed -i 's/CHANGE_PORT/'$SERVER_PORT_TCP'/g' $1/$1.ovpn && \
33 | cp $OPENVPN_CONF_DIR/keygen/ccd $OPENVPN_CONF_DIR/ccd/$1
34 | cd $1
35 | zip -r $1.zip ./*.ovpn ./*ta.key ./*.p12
36 | echo "DONE. KEY AND CONFIG:: $1.zip"
37 | else
38 | echo "you must define KEY_DIR..."
39 | fi
40 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-key-server:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Make a certificate/private key pair using a locally generated
4 | # root certificate.
5 | #
6 | # Explicitly set nsCertType to server using the "server"
7 | # extension in the openssl.cnf file.
8 |
9 | source ./vars
10 |
11 | if [[ -e $KEY_DIR/server.key ]];
12 | then
13 | echo "WARNING:server.key already exists! Exit."
14 | exit 1
15 | fi
16 |
17 | export EASY_RSA="${EASY_RSA:-.}"
18 | "$EASY_RSA/pkitool" --server $*
19 |
20 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-key-server-tcp-commongw:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Make a certificate/private key pair using a locally generated
4 | # root certificate.
5 | #
6 | # Explicitly set nsCertType to server using the "server"
7 | # extension in the openssl.cnf file.
8 |
9 | source ./vars
10 |
11 | if [[ -e $KEY_DIR/server.key ]];
12 | then
13 | echo "WARNING: server key already exist, dont touch it!"
14 | exit 1
15 | fi
16 |
17 | export EASY_RSA="${EASY_RSA:-.}"
18 | "$EASY_RSA/pkitool" --server $*
19 |
20 | mkdir -p $OPENVPN_LOG_DIR > /dev/null 2>&1 &
21 | chown nobody:root $OPENVPN_LOG_DIR > /dev/null 2>&1 &
22 |
23 | cp server-template-tcp-commongw.conf $OPENVPN_CONF_DIR/server-tcp-gw.conf
24 | sed -i 's/CHANGE_PORT/'$SERVER_PORT_TCP'/g' $OPENVPN_CONF_DIR/server-tcp-gw.conf
25 | cp server-startup-template-tcp-gw.sh $OPENVPN_CONF_DIR/server-tcp-gw-startup.sh
26 |
27 |
28 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-req:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Build a certificate signing request and private key. Use this
4 | # when your root certificate and key is not available locally.
5 |
6 | source ./vars
7 |
8 | if [[ -e $KEY_DIR/server.csr ]];
9 | then
10 | echo "WARNING:server.csr already exists! Exit."
11 | exit 1
12 | fi
13 |
14 | export EASY_RSA="${EASY_RSA:-.}"
15 | "$EASY_RSA/pkitool" --csr $*
16 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-req-pass:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Like build-req, but protect your private key
4 | # with a password.
5 |
6 | source ./vars
7 |
8 | if [[ -e $KEY_DIR/server.csr ]];
9 | then
10 | echo "WARNING:server.csr already exists! Exit."
11 | exit 1
12 | fi
13 |
14 | export EASY_RSA="${EASY_RSA:-.}"
15 | "$EASY_RSA/pkitool" --csr --pass $*
16 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/build-ta:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Build Diffie-Hellman parameters for the server side
4 | # of an SSL/TLS connection.
5 |
6 | source ./vars
7 |
8 | if [[ -e $KEY_DIR/ta.key ]];
9 | then
10 | echo "WARNING:ta.key already exists! Exit."
11 | exit 1
12 | fi
13 |
14 | openvpn --genkey -b 2048 --secret ${KEY_DIR}/ta.key
15 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/ccd:
--------------------------------------------------------------------------------
1 | iroute 10.8.2.0 255.255.255.0
2 |
3 |
4 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/ccd-tcp:
--------------------------------------------------------------------------------
1 | iroute 10.8.3.0 255.255.255.0
2 |
3 |
4 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/clean-all:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Initialize the $KEY_DIR directory.
4 | # Note that this script does a
5 | # rm -rf on $KEY_DIR so be careful!
6 |
7 | echo ""
8 | echo "##################################"
9 | echo "WARNING! You are goung to purge EVERYTHING from OpenVPN!"
10 | echo "##################################"
11 | echo ""
12 | read -p "ARE YOU SURE? [y/n]" -n 1 -r
13 | echo # (optional) move to a new line
14 | if [[ ! $REPLY =~ ^[Yy]$ ]]
15 | then
16 | [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
17 | fi
18 |
19 | source ./vars
20 |
21 | if [ "$KEY_DIR" ]; then
22 | rm -rf "$KEY_DIR"
23 | mkdir "$KEY_DIR" && \
24 | chmod go-rwx "$KEY_DIR" && \
25 | touch "$KEY_DIR/index.txt" && \
26 | echo 01 >"$KEY_DIR/serial"
27 | rm -rf $OPENVPN_CONF_DIR/ccd/*
28 | rm -f $OPENVPN_CONF_DIR/ipp.txt
29 | rm -f $OPENVPN_CONF_DIR/*.sh
30 | rm -f $OPENVPN_CONF_DIR/*.conf
31 | rm -f $OPENVPN_LOG_DIR/*
32 | echo ""
33 | echo "DONE."
34 | else
35 | echo 'Please source the vars script first (i.e. "source ./vars")'
36 | echo 'Make sure you have edited it to reflect your configuration.'
37 | fi
38 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/client-template-embed-commongw.ovpn:
--------------------------------------------------------------------------------
1 | client
2 | proto tcp-client
3 | dev tun
4 | remote-cert-tls server
5 | remote CHANGE_SERVER CHANGE_PORT
6 | cipher AES-256-CBC
7 | verb 3
8 | mute 20
9 | keepalive 10 120
10 | persist-key
11 | persist-tun
12 | float
13 | resolv-retry infinite
14 | nobind
15 | route-delay 10 30
16 | reneg-sec 86400
17 | tun-mtu 1300
18 | mssfix 1300
19 | pull
20 | key-direction 1
21 | tun-mtu 1300
22 | mssfix 1300
23 |
24 | CHANGE_TA_KEY_BODY
25 |
26 |
27 | CHANGE_CA_CRT_BODY
28 |
29 |
30 | CHANGE_CLIENT_CERT_BODY
31 |
32 |
33 | CHANGE_CLIENT_KEY_BODY
34 |
35 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/client-template-embed.ovpn:
--------------------------------------------------------------------------------
1 | client
2 | proto udp
3 | dev tun
4 | remote-cert-tls server
5 | remote CHANGE_SERVER CHANGE_PORT
6 | cipher AES-256-CBC
7 | verb 3
8 | mute 20
9 | keepalive 10 120
10 | persist-key
11 | persist-tun
12 | float
13 | resolv-retry infinite
14 | nobind
15 | route-delay 10 30
16 | reneg-sec 86400
17 | tun-mtu 1300
18 | mssfix 1300
19 | pull
20 | key-direction 1
21 | tun-mtu 1300
22 | mssfix 1300
23 |
24 | CHANGE_TA_KEY_BODY
25 |
26 |
27 | CHANGE_CA_CRT_BODY
28 |
29 |
30 | CHANGE_CLIENT_CERT_BODY
31 |
32 |
33 | CHANGE_CLIENT_KEY_BODY
34 |
35 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/client-template.commongw.p12.ovpn:
--------------------------------------------------------------------------------
1 | client
2 | proto tcp-client
3 | dev tun
4 | remote-cert-tls server
5 | pkcs12 CHANGE_KEY.p12
6 | tls-auth CHANGE_TA.ta.key 1
7 | remote CHANGE_SERVER CHANGE_PORT
8 | cipher AES-256-CBC
9 | verb 3
10 | mute 20
11 | keepalive 10 120
12 | persist-key
13 | persist-tun
14 | float
15 | resolv-retry infinite
16 | nobind
17 | route-delay 10 30
18 | reneg-sec 86400
19 | pull
20 | tun-mtu 1300
21 | mssfix 1300
22 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/client-template.ovpn:
--------------------------------------------------------------------------------
1 | client
2 | proto udp
3 | dev tun
4 | ca ca.crt
5 | remote-cert-tls server
6 | cert CHANGE_KEY.crt
7 | key CHANGE_KEY.key
8 | remote CHANGE_SERVER CHANGE_PORT
9 | tls-auth CHANGE_TA.ta.key 1
10 | cipher AES-256-CBC
11 | verb 3
12 | mute 20
13 | keepalive 10 120
14 | persist-key
15 | persist-tun
16 | float
17 | resolv-retry infinite
18 | nobind
19 | route-delay 10 30
20 | reneg-sec 86400
21 | pull
22 | tun-mtu 1300
23 | mssfix 1300
24 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/client-template.p12.ovpn:
--------------------------------------------------------------------------------
1 | client
2 | proto udp
3 | dev tun
4 | remote-cert-tls server
5 | pkcs12 CHANGE_KEY.p12
6 | tls-auth CHANGE_TA.ta.key 1
7 | remote CHANGE_SERVER CHANGE_PORT
8 | cipher AES-256-CBC
9 | verb 3
10 | mute 20
11 | keepalive 10 120
12 | persist-key
13 | persist-tun
14 | float
15 | resolv-retry infinite
16 | nobind
17 | route-delay 10 30
18 | reneg-sec 86400
19 | pull
20 | tun-mtu 1300
21 | mssfix 1300
22 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/create-server:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ./vars
4 |
5 | if [[ -e $KEY_DIR/server.key ]];
6 | then
7 | echo "WARNING: server key already exists! Exit."
8 | exit 1
9 | fi
10 |
11 | mkdir -p $KEY_DIR
12 | chmod og+X $KEY_DIR
13 |
14 | mkdir -p $OPENVPN_CONF_DIR/ccd
15 | chmod og+X $OPENVPN_CONF_DIR/ccd
16 |
17 | mkdir "$KEY_DIR"
18 | chmod go-rwx "$KEY_DIR"
19 | chmod og+rX "$KEY_DIR"
20 | touch "$KEY_DIR/index.txt"
21 | echo 01 >"$KEY_DIR/serial"
22 |
23 |
24 | ./build-ca
25 | ./build-key-server server
26 | ./build-dh
27 | ./build-ta
28 | ./build-crl-revoke
29 |
30 | mkdir -p $OPENVPN_LOG_DIR
31 | chown nobody:root $OPENVPN_LOG_DIR
32 | chmod -R og+rwX $OPENVPN_LOG_DIR
33 |
34 | cp server-template.conf $OPENVPN_CONF_DIR/server.conf
35 | sed -i 's/CHANGE_PORT/'$SERVER_PORT_UDP'/g' $OPENVPN_CONF_DIR/server.conf
36 | cp server-startup-template.sh $OPENVPN_CONF_DIR/server-startup.sh
37 |
38 |
39 | echo "###########################"
40 | echo "DONE, START:"
41 | echo "service openvpn@server start"
42 | echo "###########################"
43 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/create-server-tcp-gw:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ./vars
4 |
5 | if [[ -e $KEY_DIR/server.key ]];
6 | then
7 | echo "WARNING: server key already exists. Exit."
8 | exit 1
9 | fi
10 |
11 | mkdir -p $KEY_DIR
12 | chmod og+X $KEY_DIR
13 |
14 | mkdir -p $OPENVPN_CONF_DIR/ccd
15 | chmod og+X $OPENVPN_CONF_DIR/ccd
16 |
17 | mkdir "$KEY_DIR"
18 | chmod go-rwx "$KEY_DIR"
19 | chmod og+rX "$KEY_DIR"
20 | touch "$KEY_DIR/index.txt" && \
21 | echo 01 >"$KEY_DIR/serial"
22 |
23 |
24 | ./build-ca
25 | ./build-key-server-tcp-commongw server
26 | ./build-dh
27 | ./build-ta
28 | ./build-crl-revoke
29 |
30 | mkdir -p $OPENVPN_LOG_DIR
31 | chown nobody:root $OPENVPN_LOG_DIR
32 | chmod -R og+rwX $OPENVPN_LOG_DIR
33 |
34 | cp server-template-tcp-commongw.conf $OPENVPN_CONF_DIR/server-tcp-gw.conf
35 | sed -i 's/CHANGE_PORT/'$SERVER_PORT_TCP'/g' $OPENVPN_CONF_DIR/server-tcp-gw.conf
36 | cp server-startup-template-tcp-gw.sh $OPENVPN_CONF_DIR/server-tcp-gw-startup.sh
37 |
38 |
39 | echo "###########################"
40 | echo "DONE, START:"
41 | echo "service openvpn@server-tcp-gw start"
42 | echo "###########################"
43 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/inherit-inter:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Build a new PKI which is rooted on an intermediate certificate generated
4 | # by ./build-inter or ./pkitool --inter from a parent PKI. The new PKI should
5 | # have independent vars settings, and must use a different KEY_DIR directory
6 | # from the parent. This tool can be used to generate arbitrary depth
7 | # certificate chains.
8 | #
9 | # To build an intermediate CA, follow the same steps for a regular PKI but
10 | # replace ./build-key or ./pkitool --initca with this script.
11 |
12 | # The EXPORT_CA file will contain the CA certificate chain and should be
13 | # referenced by the OpenVPN "ca" directive in config files. The ca.crt file
14 | # will only contain the local intermediate CA -- it's needed by the easy-rsa
15 | # scripts but not by OpenVPN directly.
16 |
17 | source ./vars
18 |
19 | EXPORT_CA="export-ca.crt"
20 |
21 | if [ $# -ne 2 ]; then
22 | echo "usage: $0 "
23 | echo "parent-key-dir: the KEY_DIR directory of the parent PKI"
24 | echo "common-name: the common name of the intermediate certificate in the parent PKI"
25 | exit 1;
26 | fi
27 |
28 | if [ "$KEY_DIR" ]; then
29 | cp "$1/$2.crt" "$KEY_DIR/ca.crt"
30 | cp "$1/$2.key" "$KEY_DIR/ca.key"
31 |
32 | if [ -e "$1/$EXPORT_CA" ]; then
33 | PARENT_CA="$1/$EXPORT_CA"
34 | else
35 | PARENT_CA="$1/ca.crt"
36 | fi
37 | cp "$PARENT_CA" "$KEY_DIR/$EXPORT_CA"
38 | cat "$KEY_DIR/ca.crt" >> "$KEY_DIR/$EXPORT_CA"
39 | else
40 | echo 'Please source the vars script first (i.e. "source ./vars")'
41 | echo 'Make sure you have edited it to reflect your configuration.'
42 | fi
43 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/list-crl:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # list revoked certificates
4 |
5 | source ./vars
6 |
7 | CRL="${1:-crl.pem}"
8 |
9 | if [ "$KEY_DIR" ]; then
10 | cd "$KEY_DIR" && \
11 | $OPENSSL crl -text -noout -in "$CRL"
12 | else
13 | echo 'Please source the vars script first (i.e. "source ./vars")'
14 | echo 'Make sure you have edited it to reflect your configuration.'
15 | fi
16 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/openssl-0.9.6.cnf:
--------------------------------------------------------------------------------
1 | # For use with easy-rsa version 2.0
2 |
3 | #
4 | # OpenSSL example configuration file.
5 | # This is mostly being used for generation of certificate requests.
6 | #
7 |
8 | # This definition stops the following lines choking if HOME isn't
9 | # defined.
10 | HOME = .
11 | RANDFILE = $ENV::HOME/.rnd
12 |
13 | # Extra OBJECT IDENTIFIER info:
14 | #oid_file = $ENV::HOME/.oid
15 | oid_section = new_oids
16 |
17 | # To use this configuration file with the "-extfile" option of the
18 | # "openssl x509" utility, name here the section containing the
19 | # X.509v3 extensions to use:
20 | # extensions =
21 | # (Alternatively, use a configuration file that has only
22 | # X.509v3 extensions in its main [= default] section.)
23 |
24 | [ new_oids ]
25 |
26 | # We can add new OIDs in here for use by 'ca' and 'req'.
27 | # Add a simple OID like this:
28 | # testoid1=1.2.3.4
29 | # Or use config file substitution like this:
30 | # testoid2=${testoid1}.5.6
31 |
32 | ####################################################################
33 | [ ca ]
34 | default_ca = CA_default # The default ca section
35 |
36 | ####################################################################
37 | [ CA_default ]
38 |
39 | dir = $ENV::KEY_DIR # Where everything is kept
40 | certs = $dir # Where the issued certs are kept
41 | crl_dir = $dir # Where the issued crl are kept
42 | database = $dir/index.txt # database index file.
43 | new_certs_dir = $dir # default place for new certs.
44 |
45 | certificate = $dir/ca.crt # The CA certificate
46 | serial = $dir/serial # The current serial number
47 | crl = $dir/crl.pem # The current CRL
48 | private_key = $dir/ca.key # The private key
49 | RANDFILE = $dir/.rand # private random number file
50 |
51 | x509_extensions = usr_cert # The extentions to add to the cert
52 |
53 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
54 | # so this is commented out by default to leave a V1 CRL.
55 | # crl_extensions = crl_ext
56 |
57 | default_days = $ENV::CA_EXPIRE # how long to certify for
58 | default_crl_days= $ENV::CRL_EXPIRE # how long before next CRL
59 | default_md = sha256 # which md to use.
60 | preserve = no # keep passed DN ordering
61 |
62 | # A few difference way of specifying how similar the request should look
63 | # For type CA, the listed attributes must be the same, and the optional
64 | # and supplied fields are just that :-)
65 | policy = policy_anything
66 |
67 | # For the CA policy
68 | [ policy_match ]
69 | countryName = match
70 | stateOrProvinceName = match
71 | organizationName = match
72 | organizationalUnitName = optional
73 | commonName = supplied
74 | emailAddress = optional
75 |
76 | # For the 'anything' policy
77 | # At this point in time, you must list all acceptable 'object'
78 | # types.
79 | [ policy_anything ]
80 | countryName = optional
81 | stateOrProvinceName = optional
82 | localityName = optional
83 | organizationName = optional
84 | organizationalUnitName = optional
85 | commonName = supplied
86 | emailAddress = optional
87 |
88 | ####################################################################
89 | [ req ]
90 | default_bits = $ENV::KEY_SIZE
91 | default_keyfile = privkey.pem
92 | default_md = sha256
93 | distinguished_name = req_distinguished_name
94 | attributes = req_attributes
95 | x509_extensions = v3_ca # The extentions to add to the self signed cert
96 |
97 | # Passwords for private keys if not present they will be prompted for
98 | # input_password = secret
99 | # output_password = secret
100 |
101 | # This sets a mask for permitted string types. There are several options.
102 | # default: PrintableString, T61String, BMPString.
103 | # pkix : PrintableString, BMPString.
104 | # utf8only: only UTF8Strings.
105 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
106 | # MASK:XXXX a literal mask value.
107 | # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
108 | # so use this option with caution!
109 | string_mask = nombstr
110 |
111 | # req_extensions = v3_req # The extensions to add to a certificate request
112 |
113 | [ req_distinguished_name ]
114 | countryName = Country Name (2 letter code)
115 | countryName_default = $ENV::KEY_COUNTRY
116 | countryName_min = 2
117 | countryName_max = 2
118 |
119 | stateOrProvinceName = State or Province Name (full name)
120 | stateOrProvinceName_default = $ENV::KEY_PROVINCE
121 |
122 | localityName = Locality Name (eg, city)
123 | localityName_default = $ENV::KEY_CITY
124 |
125 | 0.organizationName = Organization Name (eg, company)
126 | 0.organizationName_default = $ENV::KEY_ORG
127 |
128 | # we can do this but it is not needed normally :-)
129 | #1.organizationName = Second Organization Name (eg, company)
130 | #1.organizationName_default = World Wide Web Pty Ltd
131 |
132 | organizationalUnitName = Organizational Unit Name (eg, section)
133 | #organizationalUnitName_default =
134 |
135 | commonName = Common Name (eg, your name or your server\'s hostname)
136 | commonName_max = 64
137 |
138 | emailAddress = Email Address
139 | emailAddress_default = $ENV::KEY_EMAIL
140 | emailAddress_max = 40
141 |
142 | # JY -- added for batch mode
143 | organizationalUnitName_default = $ENV::KEY_OU
144 | commonName_default = $ENV::KEY_CN
145 |
146 | # SET-ex3 = SET extension number 3
147 |
148 | [ req_attributes ]
149 | challengePassword = A challenge password
150 | challengePassword_min = 4
151 | challengePassword_max = 20
152 |
153 | unstructuredName = An optional company name
154 |
155 | [ usr_cert ]
156 |
157 | # These extensions are added when 'ca' signs a request.
158 |
159 | # This goes against PKIX guidelines but some CAs do it and some software
160 | # requires this to avoid interpreting an end user certificate as a CA.
161 |
162 | basicConstraints=CA:FALSE
163 |
164 | # Here are some examples of the usage of nsCertType. If it is omitted
165 | # the certificate can be used for anything *except* object signing.
166 |
167 | # This is OK for an SSL server.
168 | # nsCertType = server
169 |
170 | # For an object signing certificate this would be used.
171 | # nsCertType = objsign
172 |
173 | # For normal client use this is typical
174 | # nsCertType = client, email
175 |
176 | # and for everything including object signing:
177 | # nsCertType = client, email, objsign
178 |
179 | # This is typical in keyUsage for a client certificate.
180 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
181 |
182 | # This will be displayed in Netscape's comment listbox.
183 | nsComment = "Easy-RSA Generated Certificate"
184 |
185 | # PKIX recommendations harmless if included in all certificates.
186 | subjectKeyIdentifier=hash
187 | authorityKeyIdentifier=keyid,issuer:always
188 | extendedKeyUsage=clientAuth
189 | keyUsage = digitalSignature
190 |
191 | # This stuff is for subjectAltName and issuerAltname.
192 | # Import the email address.
193 | # subjectAltName=email:copy
194 | subjectAltName=$ENV::KEY_ALTNAMES
195 |
196 | # Copy subject details
197 | # issuerAltName=issuer:copy
198 |
199 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
200 | #nsBaseUrl
201 | #nsRevocationUrl
202 | #nsRenewalUrl
203 | #nsCaPolicyUrl
204 | #nsSslServerName
205 |
206 | [ server ]
207 |
208 | # JY ADDED -- Make a cert with nsCertType set to "server"
209 | basicConstraints=CA:FALSE
210 | nsCertType = server
211 | nsComment = "Easy-RSA Generated Server Certificate"
212 | subjectKeyIdentifier=hash
213 | authorityKeyIdentifier=keyid,issuer:always
214 | extendedKeyUsage=serverAuth
215 | keyUsage = digitalSignature, keyEncipherment
216 | subjectAltName=$ENV::KEY_ALTNAMES
217 |
218 | [ v3_req ]
219 |
220 | # Extensions to add to a certificate request
221 |
222 | basicConstraints = CA:FALSE
223 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
224 |
225 | [ v3_ca ]
226 |
227 |
228 | # Extensions for a typical CA
229 |
230 |
231 | # PKIX recommendation.
232 |
233 | subjectKeyIdentifier=hash
234 |
235 | authorityKeyIdentifier=keyid:always,issuer:always
236 |
237 | # This is what PKIX recommends but some broken software chokes on critical
238 | # extensions.
239 | #basicConstraints = critical,CA:true
240 | # So we do this instead.
241 | basicConstraints = CA:true
242 |
243 | # Key usage: this is typical for a CA certificate. However since it will
244 | # prevent it being used as an test self-signed certificate it is best
245 | # left out by default.
246 | # keyUsage = cRLSign, keyCertSign
247 |
248 | # Some might want this also
249 | # nsCertType = sslCA, emailCA
250 |
251 | # Include email address in subject alt name: another PKIX recommendation
252 | # subjectAltName=email:copy
253 | # Copy issuer details
254 | # issuerAltName=issuer:copy
255 |
256 | # DER hex encoding of an extension: beware experts only!
257 | # obj=DER:02:03
258 | # Where 'obj' is a standard or added object
259 | # You can even override a supported extension:
260 | # basicConstraints= critical, DER:30:03:01:01:FF
261 |
262 | [ crl_ext ]
263 |
264 | # CRL extensions.
265 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
266 |
267 | # issuerAltName=issuer:copy
268 | authorityKeyIdentifier=keyid:always,issuer:always
269 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/openssl-0.9.8.cnf:
--------------------------------------------------------------------------------
1 | # For use with easy-rsa version 2.0
2 |
3 | #
4 | # OpenSSL example configuration file.
5 | # This is mostly being used for generation of certificate requests.
6 | #
7 |
8 | # This definition stops the following lines choking if HOME isn't
9 | # defined.
10 | HOME = .
11 | RANDFILE = $ENV::HOME/.rnd
12 | openssl_conf = openssl_init
13 |
14 | [ openssl_init ]
15 | # Extra OBJECT IDENTIFIER info:
16 | #oid_file = $ENV::HOME/.oid
17 | oid_section = new_oids
18 | engines = engine_section
19 |
20 | # To use this configuration file with the "-extfile" option of the
21 | # "openssl x509" utility, name here the section containing the
22 | # X.509v3 extensions to use:
23 | # extensions =
24 | # (Alternatively, use a configuration file that has only
25 | # X.509v3 extensions in its main [= default] section.)
26 |
27 | [ new_oids ]
28 |
29 | # We can add new OIDs in here for use by 'ca' and 'req'.
30 | # Add a simple OID like this:
31 | # testoid1=1.2.3.4
32 | # Or use config file substitution like this:
33 | # testoid2=${testoid1}.5.6
34 |
35 | ####################################################################
36 | [ ca ]
37 | default_ca = CA_default # The default ca section
38 |
39 | ####################################################################
40 | [ CA_default ]
41 |
42 | dir = $ENV::KEY_DIR # Where everything is kept
43 | certs = $dir # Where the issued certs are kept
44 | crl_dir = $dir # Where the issued crl are kept
45 | database = $dir/index.txt # database index file.
46 | new_certs_dir = $dir # default place for new certs.
47 |
48 | certificate = $dir/ca.crt # The CA certificate
49 | serial = $dir/serial # The current serial number
50 | crl = $dir/crl.pem # The current CRL
51 | private_key = $dir/ca.key # The private key
52 | RANDFILE = $dir/.rand # private random number file
53 |
54 | x509_extensions = usr_cert # The extentions to add to the cert
55 |
56 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
57 | # so this is commented out by default to leave a V1 CRL.
58 | # crl_extensions = crl_ext
59 |
60 | default_days = $ENV::CA_EXPIRE # how long to certify for
61 | default_crl_days= $ENV::CRL_EXPIRE # how long before next CRL
62 | default_md = sha256 # which md to use.
63 | preserve = no # keep passed DN ordering
64 |
65 | # A few difference way of specifying how similar the request should look
66 | # For type CA, the listed attributes must be the same, and the optional
67 | # and supplied fields are just that :-)
68 | policy = policy_anything
69 |
70 | # For the CA policy
71 | [ policy_match ]
72 | countryName = match
73 | stateOrProvinceName = match
74 | organizationName = match
75 | organizationalUnitName = optional
76 | commonName = supplied
77 | name = optional
78 | emailAddress = optional
79 |
80 | # For the 'anything' policy
81 | # At this point in time, you must list all acceptable 'object'
82 | # types.
83 | [ policy_anything ]
84 | countryName = optional
85 | stateOrProvinceName = optional
86 | localityName = optional
87 | organizationName = optional
88 | organizationalUnitName = optional
89 | commonName = supplied
90 | name = optional
91 | emailAddress = optional
92 |
93 | ####################################################################
94 | [ req ]
95 | default_bits = $ENV::KEY_SIZE
96 | default_keyfile = privkey.pem
97 | default_md = sha256
98 | distinguished_name = req_distinguished_name
99 | attributes = req_attributes
100 | x509_extensions = v3_ca # The extentions to add to the self signed cert
101 |
102 | # Passwords for private keys if not present they will be prompted for
103 | # input_password = secret
104 | # output_password = secret
105 |
106 | # This sets a mask for permitted string types. There are several options.
107 | # default: PrintableString, T61String, BMPString.
108 | # pkix : PrintableString, BMPString.
109 | # utf8only: only UTF8Strings.
110 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
111 | # MASK:XXXX a literal mask value.
112 | # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
113 | # so use this option with caution!
114 | string_mask = nombstr
115 |
116 | # req_extensions = v3_req # The extensions to add to a certificate request
117 |
118 | [ req_distinguished_name ]
119 | countryName = Country Name (2 letter code)
120 | countryName_default = $ENV::KEY_COUNTRY
121 | countryName_min = 2
122 | countryName_max = 2
123 |
124 | stateOrProvinceName = State or Province Name (full name)
125 | stateOrProvinceName_default = $ENV::KEY_PROVINCE
126 |
127 | localityName = Locality Name (eg, city)
128 | localityName_default = $ENV::KEY_CITY
129 |
130 | 0.organizationName = Organization Name (eg, company)
131 | 0.organizationName_default = $ENV::KEY_ORG
132 |
133 | # we can do this but it is not needed normally :-)
134 | #1.organizationName = Second Organization Name (eg, company)
135 | #1.organizationName_default = World Wide Web Pty Ltd
136 |
137 | organizationalUnitName = Organizational Unit Name (eg, section)
138 | #organizationalUnitName_default =
139 |
140 | commonName = Common Name (eg, your name or your server\'s hostname)
141 | commonName_max = 64
142 |
143 | name = Name
144 | name_max = 64
145 |
146 | emailAddress = Email Address
147 | emailAddress_default = $ENV::KEY_EMAIL
148 | emailAddress_max = 40
149 |
150 | # JY -- added for batch mode
151 | organizationalUnitName_default = $ENV::KEY_OU
152 | commonName_default = $ENV::KEY_CN
153 | name_default = $ENV::KEY_NAME
154 |
155 | # SET-ex3 = SET extension number 3
156 |
157 | [ req_attributes ]
158 | challengePassword = A challenge password
159 | challengePassword_min = 4
160 | challengePassword_max = 20
161 |
162 | unstructuredName = An optional company name
163 |
164 | [ usr_cert ]
165 |
166 | # These extensions are added when 'ca' signs a request.
167 |
168 | # This goes against PKIX guidelines but some CAs do it and some software
169 | # requires this to avoid interpreting an end user certificate as a CA.
170 |
171 | basicConstraints=CA:FALSE
172 |
173 | # Here are some examples of the usage of nsCertType. If it is omitted
174 | # the certificate can be used for anything *except* object signing.
175 |
176 | # This is OK for an SSL server.
177 | # nsCertType = server
178 |
179 | # For an object signing certificate this would be used.
180 | # nsCertType = objsign
181 |
182 | # For normal client use this is typical
183 | # nsCertType = client, email
184 |
185 | # and for everything including object signing:
186 | # nsCertType = client, email, objsign
187 |
188 | # This is typical in keyUsage for a client certificate.
189 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
190 |
191 | # This will be displayed in Netscape's comment listbox.
192 | nsComment = "Easy-RSA Generated Certificate"
193 |
194 | # PKIX recommendations harmless if included in all certificates.
195 | subjectKeyIdentifier=hash
196 | authorityKeyIdentifier=keyid,issuer:always
197 | extendedKeyUsage=clientAuth
198 | keyUsage = digitalSignature
199 |
200 | # This stuff is for subjectAltName and issuerAltname.
201 | # Import the email address.
202 | # subjectAltName=email:copy
203 | subjectAltName=$ENV::KEY_ALTNAMES
204 |
205 | # Copy subject details
206 | # issuerAltName=issuer:copy
207 |
208 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
209 | #nsBaseUrl
210 | #nsRevocationUrl
211 | #nsRenewalUrl
212 | #nsCaPolicyUrl
213 | #nsSslServerName
214 |
215 | [ server ]
216 |
217 | # JY ADDED -- Make a cert with nsCertType set to "server"
218 | basicConstraints=CA:FALSE
219 | nsCertType = server
220 | nsComment = "Easy-RSA Generated Server Certificate"
221 | subjectKeyIdentifier=hash
222 | authorityKeyIdentifier=keyid,issuer:always
223 | extendedKeyUsage=serverAuth
224 | keyUsage = digitalSignature, keyEncipherment
225 | subjectAltName=$ENV::KEY_ALTNAMES
226 |
227 | [ v3_req ]
228 |
229 | # Extensions to add to a certificate request
230 |
231 | basicConstraints = CA:FALSE
232 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
233 |
234 | [ v3_ca ]
235 |
236 |
237 | # Extensions for a typical CA
238 |
239 |
240 | # PKIX recommendation.
241 |
242 | subjectKeyIdentifier=hash
243 |
244 | authorityKeyIdentifier=keyid:always,issuer:always
245 |
246 | # This is what PKIX recommends but some broken software chokes on critical
247 | # extensions.
248 | #basicConstraints = critical,CA:true
249 | # So we do this instead.
250 | basicConstraints = CA:true
251 |
252 | # Key usage: this is typical for a CA certificate. However since it will
253 | # prevent it being used as an test self-signed certificate it is best
254 | # left out by default.
255 | # keyUsage = cRLSign, keyCertSign
256 |
257 | # Some might want this also
258 | # nsCertType = sslCA, emailCA
259 |
260 | # Include email address in subject alt name: another PKIX recommendation
261 | # subjectAltName=email:copy
262 | # Copy issuer details
263 | # issuerAltName=issuer:copy
264 |
265 | # DER hex encoding of an extension: beware experts only!
266 | # obj=DER:02:03
267 | # Where 'obj' is a standard or added object
268 | # You can even override a supported extension:
269 | # basicConstraints= critical, DER:30:03:01:01:FF
270 |
271 | [ crl_ext ]
272 |
273 | # CRL extensions.
274 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
275 |
276 | # issuerAltName=issuer:copy
277 | authorityKeyIdentifier=keyid:always,issuer:always
278 |
279 | [ engine_section ]
280 | #
281 | # If you are using PKCS#11
282 | # Install engine_pkcs11 of opensc (www.opensc.org)
283 | # And uncomment the following
284 | # verify that dynamic_path points to the correct location
285 | #
286 | #pkcs11 = pkcs11_section
287 |
288 | [ pkcs11_section ]
289 | engine_id = pkcs11
290 | dynamic_path = /usr/lib/engines/engine_pkcs11.so
291 | MODULE_PATH = $ENV::PKCS11_MODULE_PATH
292 | PIN = $ENV::PKCS11_PIN
293 | init = 0
294 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/openssl-1.0.0.cnf:
--------------------------------------------------------------------------------
1 | # For use with easy-rsa version 2.0
2 |
3 | #
4 | # OpenSSL example configuration file.
5 | # This is mostly being used for generation of certificate requests.
6 | #
7 |
8 | # This definition stops the following lines choking if HOME isn't
9 | # defined.
10 | HOME = .
11 | RANDFILE = $ENV::HOME/.rnd
12 | openssl_conf = openssl_init
13 |
14 | [ openssl_init ]
15 | # Extra OBJECT IDENTIFIER info:
16 | #oid_file = $ENV::HOME/.oid
17 | oid_section = new_oids
18 | engines = engine_section
19 |
20 | # To use this configuration file with the "-extfile" option of the
21 | # "openssl x509" utility, name here the section containing the
22 | # X.509v3 extensions to use:
23 | # extensions =
24 | # (Alternatively, use a configuration file that has only
25 | # X.509v3 extensions in its main [= default] section.)
26 |
27 | [ new_oids ]
28 |
29 | # We can add new OIDs in here for use by 'ca' and 'req'.
30 | # Add a simple OID like this:
31 | # testoid1=1.2.3.4
32 | # Or use config file substitution like this:
33 | # testoid2=${testoid1}.5.6
34 |
35 | ####################################################################
36 | [ ca ]
37 | default_ca = CA_default # The default ca section
38 |
39 | ####################################################################
40 | [ CA_default ]
41 |
42 | dir = $ENV::KEY_DIR # Where everything is kept
43 | certs = $dir # Where the issued certs are kept
44 | crl_dir = $dir # Where the issued crl are kept
45 | database = $dir/index.txt # database index file.
46 | new_certs_dir = $dir # default place for new certs.
47 |
48 | certificate = $dir/ca.crt # The CA certificate
49 | serial = $dir/serial # The current serial number
50 | crl = $dir/crl.pem # The current CRL
51 | private_key = $dir/ca.key # The private key
52 | RANDFILE = $dir/.rand # private random number file
53 |
54 | x509_extensions = usr_cert # The extentions to add to the cert
55 |
56 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
57 | # so this is commented out by default to leave a V1 CRL.
58 | # crl_extensions = crl_ext
59 |
60 | default_days = $ENV::CA_EXPIRE # how long to certify for
61 | default_crl_days = $ENV::CRL_EXPIRE # how long before next CRL
62 | default_md = sha256 # which md to use.
63 | preserve = no # keep passed DN ordering
64 |
65 | # A few difference way of specifying how similar the request should look
66 | # For type CA, the listed attributes must be the same, and the optional
67 | # and supplied fields are just that :-)
68 | policy = policy_anything
69 |
70 | # For the CA policy
71 | [ policy_match ]
72 | countryName = match
73 | stateOrProvinceName = match
74 | organizationName = match
75 | organizationalUnitName = optional
76 | commonName = supplied
77 | emailAddress = optional
78 |
79 | # For the 'anything' policy
80 | # At this point in time, you must list all acceptable 'object'
81 | # types.
82 | [ policy_anything ]
83 | countryName = optional
84 | stateOrProvinceName = optional
85 | localityName = optional
86 | organizationName = optional
87 | organizationalUnitName = optional
88 | commonName = supplied
89 | emailAddress = optional
90 |
91 | ####################################################################
92 | [ req ]
93 | default_bits = $ENV::KEY_SIZE
94 | default_keyfile = privkey.pem
95 | default_md = sha256
96 | distinguished_name = req_distinguished_name
97 | attributes = req_attributes
98 | x509_extensions = v3_ca # The extentions to add to the self signed cert
99 |
100 | # Passwords for private keys if not present they will be prompted for
101 | # input_password = secret
102 | # output_password = secret
103 |
104 | # This sets a mask for permitted string types. There are several options.
105 | # default: PrintableString, T61String, BMPString.
106 | # pkix : PrintableString, BMPString.
107 | # utf8only: only UTF8Strings.
108 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
109 | # MASK:XXXX a literal mask value.
110 | # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
111 | # so use this option with caution!
112 | string_mask = nombstr
113 |
114 | # req_extensions = v3_req # The extensions to add to a certificate request
115 |
116 | [ req_distinguished_name ]
117 | countryName = Country Name (2 letter code)
118 | countryName_default = $ENV::KEY_COUNTRY
119 | countryName_min = 2
120 | countryName_max = 2
121 |
122 | stateOrProvinceName = State or Province Name (full name)
123 | stateOrProvinceName_default = $ENV::KEY_PROVINCE
124 |
125 | localityName = Locality Name (eg, city)
126 | localityName_default = $ENV::KEY_CITY
127 |
128 | 0.organizationName = Organization Name (eg, company)
129 | 0.organizationName_default = $ENV::KEY_ORG
130 |
131 | # we can do this but it is not needed normally :-)
132 | #1.organizationName = Second Organization Name (eg, company)
133 | #1.organizationName_default = World Wide Web Pty Ltd
134 |
135 | organizationalUnitName = Organizational Unit Name (eg, section)
136 | #organizationalUnitName_default =
137 |
138 | commonName = Common Name (eg, your name or your server\'s hostname)
139 | commonName_max = 64
140 |
141 | emailAddress = Email Address
142 | emailAddress_default = $ENV::KEY_EMAIL
143 | emailAddress_max = 40
144 |
145 | # JY -- added for batch mode
146 | organizationalUnitName_default = $ENV::KEY_OU
147 | commonName_default = $ENV::KEY_CN
148 |
149 | # SET-ex3 = SET extension number 3
150 |
151 | [ req_attributes ]
152 | challengePassword = A challenge password
153 | challengePassword_min = 4
154 | challengePassword_max = 20
155 |
156 | unstructuredName = An optional company name
157 |
158 | [ usr_cert ]
159 |
160 | # These extensions are added when 'ca' signs a request.
161 |
162 | # This goes against PKIX guidelines but some CAs do it and some software
163 | # requires this to avoid interpreting an end user certificate as a CA.
164 |
165 | basicConstraints=CA:FALSE
166 |
167 | # Here are some examples of the usage of nsCertType. If it is omitted
168 | # the certificate can be used for anything *except* object signing.
169 |
170 | # This is OK for an SSL server.
171 | # nsCertType = server
172 |
173 | # For an object signing certificate this would be used.
174 | # nsCertType = objsign
175 |
176 | # For normal client use this is typical
177 | # nsCertType = client, email
178 |
179 | # and for everything including object signing:
180 | # nsCertType = client, email, objsign
181 |
182 | # This is typical in keyUsage for a client certificate.
183 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
184 |
185 | # This will be displayed in Netscape's comment listbox.
186 | nsComment = "Easy-RSA Generated Certificate"
187 |
188 | # PKIX recommendations harmless if included in all certificates.
189 | subjectKeyIdentifier=hash
190 | authorityKeyIdentifier=keyid,issuer:always
191 | extendedKeyUsage=clientAuth
192 | keyUsage = digitalSignature
193 |
194 | # This stuff is for subjectAltName and issuerAltname.
195 | # Import the email address.
196 | # subjectAltName=email:copy
197 |
198 | # Copy subject details
199 | # issuerAltName=issuer:copy
200 |
201 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
202 | #nsBaseUrl
203 | #nsRevocationUrl
204 | #nsRenewalUrl
205 | #nsCaPolicyUrl
206 | #nsSslServerName
207 |
208 | [ server ]
209 |
210 | # JY ADDED -- Make a cert with nsCertType set to "server"
211 | basicConstraints=CA:FALSE
212 | nsCertType = server
213 | nsComment = "Easy-RSA Generated Server Certificate"
214 | subjectKeyIdentifier=hash
215 | authorityKeyIdentifier=keyid,issuer:always
216 | extendedKeyUsage=serverAuth
217 | keyUsage = digitalSignature, keyEncipherment
218 |
219 | [ v3_req ]
220 |
221 | # Extensions to add to a certificate request
222 |
223 | basicConstraints = CA:FALSE
224 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
225 |
226 | [ v3_ca ]
227 |
228 |
229 | # Extensions for a typical CA
230 |
231 |
232 | # PKIX recommendation.
233 |
234 | subjectKeyIdentifier=hash
235 |
236 | authorityKeyIdentifier=keyid:always,issuer:always
237 |
238 | # This is what PKIX recommends but some broken software chokes on critical
239 | # extensions.
240 | #basicConstraints = critical,CA:true
241 | # So we do this instead.
242 | basicConstraints = CA:true
243 |
244 | # Key usage: this is typical for a CA certificate. However since it will
245 | # prevent it being used as an test self-signed certificate it is best
246 | # left out by default.
247 | # keyUsage = cRLSign, keyCertSign
248 |
249 | # Some might want this also
250 | # nsCertType = sslCA, emailCA
251 |
252 | # Include email address in subject alt name: another PKIX recommendation
253 | # subjectAltName=email:copy
254 | # Copy issuer details
255 | # issuerAltName=issuer:copy
256 |
257 | # DER hex encoding of an extension: beware experts only!
258 | # obj=DER:02:03
259 | # Where 'obj' is a standard or added object
260 | # You can even override a supported extension:
261 | # basicConstraints= critical, DER:30:03:01:01:FF
262 |
263 | [ crl_ext ]
264 |
265 | # CRL extensions.
266 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
267 |
268 | # issuerAltName=issuer:copy
269 | authorityKeyIdentifier=keyid:always,issuer:always
270 |
271 | [ engine_section ]
272 | #
273 | # If you are using PKCS#11
274 | # Install engine_pkcs11 of opensc (www.opensc.org)
275 | # And uncomment the following
276 | # verify that dynamic_path points to the correct location
277 | #
278 | #pkcs11 = pkcs11_section
279 |
280 | #[ pkcs11_section ]
281 | #engine_id = pkcs11
282 | #dynamic_path = /usr/lib/engines/engine_pkcs11.so
283 | #MODULE_PATH = $ENV::PKCS11_MODULE_PATH
284 | #PIN = $ENV::PKCS11_PIN
285 | #init = 0
286 |
287 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/pem-split:
--------------------------------------------------------------------------------
1 | #!/usr/bin/awk -f
2 | #
3 | # Take a PEM format file as input and split out certs and keys into separate files
4 | # added TA keys spolitter by Tobi
5 | # Copyright, original file: https://gist.github.com/jinnko/d6867ce326e8b6e88975
6 |
7 |
8 | BEGIN { n=0; cert=0; key=0; if ( ARGC < 2 ) { print "Usage: pem-split FILENAME"; exit 1 } }
9 | /-----BEGIN PRIVATE KEY-----/ { key=1; cert=0 }
10 | /-----BEGIN OpenVPN Static key V1-----/ { key=1; cert=0 }
11 | /-----BEGIN CERTIFICATE-----/ { cert=1; key=0 }
12 | split_after == 1 { n++; split_after=0 }
13 | /-----END CERTIFICATE-----/ { split_after=1 }
14 | /-----END PRIVATE KEY-----/ { split_after=1 }
15 | /-----END OpenVPN Static key V1-----/ { split_after=1 }
16 | key == 1 { print > FILENAME "-" n ".key" }
17 | cert == 1 { print > FILENAME "-" n ".crt" }
18 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/pkitool:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # OpenVPN -- An application to securely tunnel IP networks
4 | # over a single TCP/UDP port, with support for SSL/TLS-based
5 | # session authentication and key exchange,
6 | # packet encryption, packet authentication, and
7 | # packet compression.
8 | #
9 | # Copyright (C) 2002-2010 OpenVPN Technologies, Inc.
10 | #
11 | # This program is free software; you can redistribute it and/or modify
12 | # it under the terms of the GNU General Public License version 2
13 | # as published by the Free Software Foundation.
14 | #
15 | # This program is distributed in the hope that it will be useful,
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | # GNU General Public License for more details.
19 | #
20 | # You should have received a copy of the GNU General Public License
21 | # along with this program (see the file COPYING included with this
22 | # distribution); if not, write to the Free Software Foundation, Inc.,
23 | # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 |
25 | # pkitool is a front-end for the openssl tool.
26 |
27 | # Calling scripts can set the certificate organizational
28 | # unit with the KEY_OU environmental variable.
29 |
30 | # Calling scripts can also set the KEY_NAME environmental
31 | # variable to set the "name" X509 subject field.
32 |
33 | PROGNAME=pkitool
34 | VERSION=2.0
35 | DEBUG=0
36 |
37 | die()
38 | {
39 | local m="$1"
40 |
41 | echo "$m" >&2
42 | exit 1
43 | }
44 |
45 | need_vars()
46 | {
47 | cat < root certificate (--ca)
100 | ca.key -> root key, keep secure (not directly used by OpenVPN)
101 | .crt files -> client/server certificates (--cert)
102 | .key files -> private keys, keep secure (--key)
103 | .csr files -> certificate signing request (not directly used by OpenVPN)
104 | dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh)
105 |
106 | Examples:
107 | $PROGNAME --initca -> Build root certificate
108 | $PROGNAME --initca --pass -> Build root certificate with password-protected key
109 | $PROGNAME --server server1 -> Build "server1" certificate/key
110 | $PROGNAME client1 -> Build "client1" certificate/key
111 | $PROGNAME --pass client2 -> Build password-protected "client2" certificate/key
112 | $PROGNAME --pkcs12 client3 -> Build "client3" certificate/key in PKCS#12 format
113 | $PROGNAME --csr client4 -> Build "client4" CSR to be signed by another CA
114 | $PROGNAME --sign client4 -> Sign "client4" CSR
115 | $PROGNAME --inter interca -> Build an intermediate key-signing certificate/key
116 | Also see ./inherit-inter script.
117 | $PROGNAME --pkcs11 /usr/lib/pkcs11/lib1 0 010203 "client5 id" client5
118 | -> Build "client5" certificate/key in PKCS#11 token
119 |
120 | Typical usage for initial PKI setup. Build myserver, client1, and client2 cert/keys.
121 | Protect client2 key with a password. Build DH parms. Generated files in ./keys :
122 | [edit vars with your site-specific info]
123 | source ./vars
124 | ./clean-all
125 | ./build-dh -> takes a long time, consider backgrounding
126 | ./$PROGNAME --initca
127 | ./$PROGNAME --server myserver
128 | ./$PROGNAME client1
129 | ./$PROGNAME --pass client2
130 |
131 | Typical usage for adding client cert to existing PKI:
132 | source ./vars
133 | ./$PROGNAME client-new
134 | EOM
135 | }
136 |
137 | # Set tool defaults
138 | [ -n "$OPENSSL" ] || export OPENSSL="openssl"
139 | [ -n "$PKCS11TOOL" ] || export PKCS11TOOL="pkcs11-tool"
140 | [ -n "$GREP" ] || export GREP="grep"
141 |
142 | # Set defaults
143 | DO_REQ="1"
144 | REQ_EXT=""
145 | DO_CA="1"
146 | CA_EXT=""
147 | DO_P12="0"
148 | DO_P11="0"
149 | DO_ROOT="0"
150 | NODES_REQ="-nodes"
151 | NODES_P12=""
152 | BATCH="-batch"
153 | CA="ca"
154 | # must be set or errors of openssl.cnf
155 | PKCS11_MODULE_PATH="dummy"
156 | PKCS11_PIN="dummy"
157 |
158 | # Process options
159 | while [ $# -gt 0 ]; do
160 | case "$1" in
161 | --keysize ) KEY_SIZE=$2
162 | shift;;
163 | --server ) REQ_EXT="$REQ_EXT -extensions server"
164 | CA_EXT="$CA_EXT -extensions server" ;;
165 | --batch ) BATCH="-batch" ;;
166 | --interact ) BATCH="" ;;
167 | --inter ) CA_EXT="$CA_EXT -extensions v3_ca" ;;
168 | --initca ) DO_ROOT="1" ;;
169 | --pass ) NODES_REQ="" ;;
170 | --csr ) DO_CA="0" ;;
171 | --sign ) DO_REQ="0" ;;
172 | --pkcs12 ) DO_P12="1" ;;
173 | --pkcs11 ) DO_P11="1"
174 | PKCS11_MODULE_PATH="$2"
175 | PKCS11_SLOT="$3"
176 | PKCS11_ID="$4"
177 | PKCS11_LABEL="$5"
178 | shift 4;;
179 |
180 | # standalone
181 | --pkcs11-init)
182 | PKCS11_MODULE_PATH="$2"
183 | PKCS11_SLOT="$3"
184 | PKCS11_LABEL="$4"
185 | if [ -z "$PKCS11_LABEL" ]; then
186 | die "Please specify library name, slot and label"
187 | fi
188 | $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-token --slot "$PKCS11_SLOT" \
189 | --label "$PKCS11_LABEL" &&
190 | $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-pin --slot "$PKCS11_SLOT"
191 | exit $?;;
192 | --pkcs11-slots)
193 | PKCS11_MODULE_PATH="$2"
194 | if [ -z "$PKCS11_MODULE_PATH" ]; then
195 | die "Please specify library name"
196 | fi
197 | $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-slots
198 | exit 0;;
199 | --pkcs11-objects)
200 | PKCS11_MODULE_PATH="$2"
201 | PKCS11_SLOT="$3"
202 | if [ -z "$PKCS11_SLOT" ]; then
203 | die "Please specify library name and slot"
204 | fi
205 | $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-objects --login --slot "$PKCS11_SLOT"
206 | exit 0;;
207 |
208 | --help|--usage)
209 | usage
210 | exit ;;
211 | --version)
212 | echo "$PROGNAME $VERSION"
213 | exit ;;
214 | # errors
215 | --* ) die "$PROGNAME: unknown option: $1" ;;
216 | * ) break ;;
217 | esac
218 | shift
219 | done
220 |
221 | if ! [ -z "$BATCH" ]; then
222 | if $OPENSSL version | grep 0.9.6 > /dev/null; then
223 | die "Batch mode is unsupported in openssl<0.9.7"
224 | fi
225 | fi
226 |
227 | if [ $DO_P12 -eq 1 -a $DO_P11 -eq 1 ]; then
228 | die "PKCS#11 and PKCS#12 cannot be specified together"
229 | fi
230 |
231 | if [ $DO_P11 -eq 1 ]; then
232 | if ! grep "^pkcs11.*=" "$KEY_CONFIG" > /dev/null; then
233 | die "Please edit $KEY_CONFIG and setup PKCS#11 engine"
234 | fi
235 | fi
236 |
237 | # If we are generating pkcs12, only encrypt the final step
238 | if [ $DO_P12 -eq 1 ]; then
239 | NODES_P12="$NODES_REQ"
240 | NODES_REQ="-nodes"
241 | fi
242 |
243 | if [ $DO_P11 -eq 1 ]; then
244 | if [ -z "$PKCS11_LABEL" ]; then
245 | die "PKCS#11 arguments incomplete"
246 | fi
247 | fi
248 |
249 | # If undefined, set default key expiration intervals
250 | if [ -z "$KEY_EXPIRE" ]; then
251 | KEY_EXPIRE=3650
252 | fi
253 | if [ -z "$CA_EXPIRE" ]; then
254 | CA_EXPIRE=3650
255 | fi
256 |
257 | # Set organizational unit to empty string if undefined
258 | if [ -z "$KEY_OU" ]; then
259 | KEY_OU=""
260 | fi
261 |
262 | # Set X509 Name string to empty string if undefined
263 | if [ -z "$KEY_NAME" ]; then
264 | KEY_NAME=""
265 | fi
266 |
267 | # Set KEY_CN, FN
268 | if [ $DO_ROOT -eq 1 ]; then
269 | if [ -z "$KEY_CN" ]; then
270 | if [ "$1" ]; then
271 | KEY_CN="$1"
272 | KEY_ALTNAMES="DNS:${KEY_CN}"
273 | elif [ "$KEY_ORG" ]; then
274 | KEY_CN="$KEY_ORG CA"
275 | KEY_ALTNAMES="$KEY_CN"
276 | fi
277 | fi
278 | if [ $BATCH ] && [ "$KEY_CN" ]; then
279 | echo "Using CA Common Name:" "$KEY_CN"
280 | KEY_ALTNAMES="$KEY_CN"
281 | fi
282 | FN="$KEY_CN"
283 | elif [ $BATCH ] && [ "$KEY_CN" ]; then
284 | echo "Using Common Name:" "$KEY_CN"
285 | KEY_ALTNAMES="$KEY_CN"
286 | FN="$KEY_CN"
287 | if [ "$1" ]; then
288 | FN="$1"
289 | fi
290 | else
291 | KEY_CN="$1"
292 | KEY_ALTNAMES="DNS:$1"
293 | shift
294 | while [ "x$1" != "x" ]
295 | do
296 | KEY_ALTNAMES="${KEY_ALTNAMES},DNS:$1"
297 | shift
298 | done
299 | FN="$KEY_CN"
300 | fi
301 |
302 | export CA_EXPIRE KEY_EXPIRE KEY_OU KEY_NAME KEY_CN PKCS11_MODULE_PATH PKCS11_PIN KEY_ALTNAMES
303 |
304 | # Show parameters (debugging)
305 | if [ $DEBUG -eq 1 ]; then
306 | echo DO_REQ $DO_REQ
307 | echo REQ_EXT $REQ_EXT
308 | echo DO_CA $DO_CA
309 | echo CA_EXT $CA_EXT
310 | echo NODES_REQ $NODES_REQ
311 | echo NODES_P12 $NODES_P12
312 | echo DO_P12 $DO_P12
313 | echo KEY_CN $KEY_CN
314 | echo KEY_ALTNAMES $KEY_ALTNAMES
315 | echo BATCH $BATCH
316 | echo DO_ROOT $DO_ROOT
317 | echo KEY_EXPIRE $KEY_EXPIRE
318 | echo CA_EXPIRE $CA_EXPIRE
319 | echo KEY_OU $KEY_OU
320 | echo KEY_NAME $KEY_NAME
321 | echo DO_P11 $DO_P11
322 | echo PKCS11_MODULE_PATH $PKCS11_MODULE_PATH
323 | echo PKCS11_SLOT $PKCS11_SLOT
324 | echo PKCS11_ID $PKCS11_ID
325 | echo PKCS11_LABEL $PKCS11_LABEL
326 | fi
327 |
328 | # Make sure ./vars was sourced beforehand
329 | if [ -d "$KEY_DIR" ] && [ "$KEY_CONFIG" ]; then
330 | cd "$KEY_DIR"
331 |
332 | # Make sure $KEY_CONFIG points to the correct version
333 | # of openssl.cnf
334 | if $GREP -i 'easy-rsa version 2\.[0-9]' "$KEY_CONFIG" >/dev/null; then
335 | :
336 | else
337 | echo "$PROGNAME: KEY_CONFIG (set by the ./vars script) is pointing to the wrong"
338 | echo "version of openssl.cnf: $KEY_CONFIG"
339 | echo "The correct version should have a comment that says: easy-rsa version 2.x";
340 | exit 1;
341 | fi
342 |
343 | # Build root CA
344 | if [ $DO_ROOT -eq 1 ]; then
345 | $OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE \
346 | -x509 -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" && \
347 | chmod 0600 "$CA.key"
348 | else
349 | # Make sure CA key/cert is available
350 | if [ $DO_CA -eq 1 ] || [ $DO_P12 -eq 1 ]; then
351 | if [ ! -r "$CA.crt" ] || [ ! -r "$CA.key" ]; then
352 | echo "$PROGNAME: Need a readable $CA.crt and $CA.key in $KEY_DIR"
353 | echo "Try $PROGNAME --initca to build a root certificate/key."
354 | exit 1
355 | fi
356 | fi
357 |
358 | # Generate key for PKCS#11 token
359 | PKCS11_ARGS=
360 | if [ $DO_P11 -eq 1 ]; then
361 | stty -echo
362 | echo -n "User PIN: "
363 | read -r PKCS11_PIN
364 | stty echo
365 | export PKCS11_PIN
366 |
367 | echo "Generating key pair on PKCS#11 token..."
368 | $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --keypairgen \
369 | --login --pin "$PKCS11_PIN" \
370 | --key-type rsa:1024 \
371 | --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" || exit 1
372 | PKCS11_ARGS="-engine pkcs11 -keyform engine -key $PKCS11_SLOT:$PKCS11_ID"
373 | fi
374 |
375 | # Build cert/key
376 | ( [ $DO_REQ -eq 0 ] || $OPENSSL req $BATCH $NODES_REQ -new -newkey rsa:$KEY_SIZE \
377 | -keyout "$FN.key" -out "$FN.csr" $REQ_EXT -config "$KEY_CONFIG" $PKCS11_ARGS ) && \
378 | ( [ $DO_CA -eq 0 ] || $OPENSSL ca $BATCH -days $KEY_EXPIRE -out "$FN.crt" \
379 | -in "$FN.csr" $CA_EXT -config "$KEY_CONFIG" ) && \
380 | ( [ $DO_P12 -eq 0 ] || $OPENSSL pkcs12 -export -inkey "$FN.key" \
381 | -in "$FN.crt" -certfile "$CA.crt" -out "$FN.p12" $NODES_P12 ) && \
382 | ( [ $DO_CA -eq 0 -o $DO_P11 -eq 1 ] || chmod 0600 "$FN.key" ) && \
383 | ( [ $DO_P12 -eq 0 ] || chmod 0600 "$FN.p12" )
384 |
385 | # Load certificate into PKCS#11 token
386 | if [ $DO_P11 -eq 1 ]; then
387 | $OPENSSL x509 -in "$FN.crt" -inform PEM -out "$FN.crt.der" -outform DER && \
388 | $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --write-object "$FN.crt.der" --type cert \
389 | --login --pin "$PKCS11_PIN" \
390 | --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL"
391 | [ -e "$FN.crt.der" ]; rm "$FN.crt.der"
392 | fi
393 |
394 | fi
395 |
396 | # Need definitions
397 | else
398 | need_vars
399 | fi
400 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/revoke-client:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # revoke a certificate, regenerate CRL,
4 | # and verify revocation
5 |
6 | source ./vars
7 |
8 | CRL="crl.pem"
9 | RT="revoke-test.pem"
10 |
11 | if [ $# -ne 1 ]; then
12 | echo "usage: revoke-full ";
13 | exit 1
14 | fi
15 |
16 | if [ "$KEY_DIR" ]; then
17 | echo "Revoking OpenVPN certificate: $1"
18 | cd "$KEY_DIR"
19 | rm -f "$RT"
20 |
21 | # set defaults
22 | export KEY_CN=""
23 | export KEY_OU=""
24 |
25 | # revoke key and generate a new CRL
26 | $OPENSSL ca -revoke "$1/$1.crt" -config "$KEY_CONFIG"
27 |
28 | echo "."
29 | # generate a new CRL -- try to be compatible with
30 | # intermediate PKIs
31 | $OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG"
32 | if [ -e export-ca.crt ]; then
33 | cat export-ca.crt "$CRL" >"$RT"
34 | else
35 | cat ca.crt "$CRL" >"$RT"
36 | fi
37 | echo "."
38 | echo "Verify the revocation:"
39 | # verify the revocation
40 | $OPENSSL verify -CAfile "$RT" -crl_check "$1/$1.crt"
41 | echo "DONE."
42 | else
43 | echo 'Please source the vars script first (i.e. "source ./vars")'
44 | echo 'Make sure you have edited it to reflect your configuration.'
45 | fi
46 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/server-startup-template-tcp-gw.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | main_interface=`ip r sh | grep default | awk '{print $5}'`
4 |
5 | iptables -t nat -A POSTROUTING -s 10.8.3.0/24 -o ${main_interface} -j MASQUERADE
6 | echo 1 > /proc/sys/net/ipv4/ip_forward
7 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/server-startup-template.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | main_interface=`ip r sh | grep default | awk '{print $5}'`
4 |
5 | iptables -t nat -A POSTROUTING -s 10.8.2.0/24 -o ${main_interface} -j MASQUERADE
6 | echo 1 > /proc/sys/net/ipv4/ip_forward
7 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/server-template-tcp-commongw.conf:
--------------------------------------------------------------------------------
1 | dev tun1
2 | port CHANGE_PORT
3 | proto tcp-server
4 |
5 | mode server
6 | tls-server
7 |
8 | ca /etc/openvpn/keys/ca.crt
9 | cert /etc/openvpn/keys/server.crt
10 | key /etc/openvpn/keys/server.key
11 | dh /etc/openvpn/keys/dh2048.pem
12 | tls-auth /etc/openvpn/keys/ta.key 0
13 | crl-verify /etc/openvpn/keys/crl.pem
14 |
15 | reneg-sec 86400
16 | cipher AES-256-CBC
17 |
18 | client-config-dir /etc/openvpn/ccd
19 | ifconfig-pool-persist /etc/openvpn/ipp.txt
20 |
21 | ifconfig 10.8.3.1 10.8.3.2
22 | ifconfig-pool 10.8.3.3 10.8.3.250
23 | route 10.8.3.0 255.255.255.0
24 | client-to-client
25 |
26 | push "route 10.8.3.0 255.255.255.0"
27 | push "redirect-gateway def1"
28 | push "dhcp-option DNS 8.8.4.4"
29 |
30 | ### extra push routes here
31 | ###push "route 10.0.0.0 255.255.0.0"
32 | ### push dns here
33 | ###push "register-dns"
34 | ###push "dhcp-option DNS 10.0.0.10"
35 | ###push "dhcp-option DOMAIN example.com"
36 |
37 | status /var/log/openvpn/openvpn-tcp-gw-status.log
38 | log /var/log/openvpn/openvpn-tcp-gw.log
39 |
40 | mute-replay-warnings
41 | user nobody
42 | group nogroup
43 | mute 20
44 | max-clients 255
45 | keepalive 10 60
46 | ping-timer-rem
47 |
48 | persist-key
49 | persist-tun
50 |
51 | ### startup script here (routing)
52 | script-security 2
53 | up /etc/openvpn/server-tcp-gw-startup.sh
54 | verb 3
55 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/server-template.conf:
--------------------------------------------------------------------------------
1 | dev tun0
2 | port CHANGE_PORT
3 | proto udp
4 |
5 | mode server
6 | tls-server
7 |
8 | ca /etc/openvpn/keys/ca.crt
9 | cert /etc/openvpn/keys/server.crt
10 | key /etc/openvpn/keys/server.key
11 | dh /etc/openvpn/keys/dh2048.pem
12 | tls-auth /etc/openvpn/keys/ta.key 0
13 | crl-verify /etc/openvpn/keys/crl.pem
14 |
15 | reneg-sec 86400
16 | cipher AES-256-CBC
17 |
18 | client-config-dir /etc/openvpn/ccd
19 | ifconfig-pool-persist /etc/openvpn/ipp.txt
20 |
21 | ifconfig 10.8.2.1 10.8.2.2
22 | ifconfig-pool 10.8.2.3 10.8.2.250
23 | route 10.8.2.0 255.255.255.0
24 | client-to-client
25 |
26 | push "route 10.8.2.0 255.255.255.0"
27 |
28 | ### extra push routes here
29 | ###push "route 10.0.0.0 255.255.0.0"
30 | ### push dns here
31 | ###push "register-dns"
32 | ###push "dhcp-option DNS 8.8.8.8"
33 | ###push "dhcp-option DOMAIN example.com"
34 |
35 | status /var/log/openvpn/openvpn-status.log
36 | log /var/log/openvpn/openvpn.log
37 |
38 | mute-replay-warnings
39 | user nobody
40 | group nogroup
41 | mute 20
42 | max-clients 255
43 | keepalive 10 60
44 | ping-timer-rem
45 |
46 | persist-key
47 | persist-tun
48 |
49 | ### startup script here (routing)
50 | script-security 2
51 | up /etc/openvpn/server-startup.sh
52 | verb 3
53 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/sign-req:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Sign a certificate signing request (a .csr file)
4 | # with a local root certificate and key.
5 |
6 | source ./vars
7 |
8 | if [[ -e $KEY_DIR/server.csr ]];
9 | then
10 | echo "WARNING:server.csr already exists! Exit."
11 | exit 1
12 | fi
13 |
14 | export EASY_RSA="${EASY_RSA:-.}"
15 | "$EASY_RSA/pkitool" --interact --sign $*
16 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/vars:
--------------------------------------------------------------------------------
1 | # easy-rsa parameter settings
2 |
3 | # NOTE: If you installed from an RPM,
4 | # don't edit this file in place in
5 | # /usr/share/openvpn/easy-rsa --
6 | # instead, you should copy the whole
7 | # easy-rsa directory to another location
8 | # (such as /etc/openvpn) so that your
9 | # edits will not be wiped out by a future
10 | # OpenVPN package upgrade.
11 |
12 | # This variable should point to
13 | # the top level of the easy-rsa
14 | # tree.
15 | export EASY_RSA="`pwd`"
16 |
17 | #
18 | # This variable should point to
19 | # the requested executables
20 | #
21 | export OPENSSL="openssl"
22 | export PKCS11TOOL="pkcs11-tool"
23 | export GREP="grep"
24 |
25 | # This variable should point to
26 | # the openssl.cnf file included
27 | # with easy-rsa.
28 | export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
29 |
30 | # Edit this variable to point to
31 | # your soon-to-be-created key
32 | # directory.
33 | #
34 | # WARNING: clean-all will do
35 | # a rm -rf on this directory
36 | # so make sure you define
37 | # it correctly!
38 |
39 | # Issue rm -rf warning
40 | #echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
41 |
42 | #export KEY_CN=""
43 | # In how many days should the root CA key expire?
44 | # In how many days should certificates expire?
45 | # These are the default values for fields
46 | # which will be placed in the certificate.
47 | # Don't leave any of these fields blank.
48 |
49 |
50 | ############################################
51 | # Configure these fields
52 | ############################################
53 | export OPENVPN_CONF_DIR="/etc/openvpn"
54 | export OPENVPN_LOG_DIR="/var/log/openvpn"
55 | export KEY_SIZE=2048
56 | export CA_EXPIRE=7300
57 | export KEY_EXPIRE=7300
58 | export CRL_EXPIRE=7300
59 | export KEY_COUNTRY="CC"
60 | export KEY_PROVINCE="CHANGE_PROVINCE"
61 | export KEY_CITY="CHANGE_CITY"
62 | export KEY_ORG="CHANGE_ORG"
63 | export KEY_EMAIL="CHANGE_ORG_EMAIL"
64 | export KEY_OU="CHANGE_OU"
65 | export SERVER_ENDPOINT="CHANGE_SERVER_IP"
66 | export SERVER_PORT_TCP="443"
67 | export SERVER_PORT_UDP="1194"
68 | export KEY_DIR="$OPENVPN_CONF_DIR/keys"
69 |
--------------------------------------------------------------------------------
/easy-openvpn/keygen/whichopensslcnf:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 |
4 | cnf="$1/openssl.cnf"
5 |
6 | if [ "$OPENSSL" ]; then
7 | if $OPENSSL version | grep -E "0\.9\.6[[:alnum:]]?" > /dev/null; then
8 | cnf="$1/openssl-0.9.6.cnf"
9 | elif $OPENSSL version | grep -E "0\.9\.8[[:alnum:]]?" > /dev/null; then
10 | cnf="$1/openssl-0.9.8.cnf"
11 | elif $OPENSSL version | grep -E "1\.0\.[[:digit:]][[:alnum:]]?" > /dev/null; then
12 | cnf="$1/openssl-1.0.0.cnf"
13 | else
14 | cnf="$1/openssl.cnf"
15 | fi
16 | fi
17 |
18 | echo $cnf
19 |
20 | if [ ! -r $cnf ]; then
21 | echo "**************************************************************" >&2
22 | echo " No $cnf file could be found" >&2
23 | echo " Further invocations will fail" >&2
24 | echo "**************************************************************" >&2
25 | fi
26 |
27 | exit 0
28 |
--------------------------------------------------------------------------------