Spaces:
No application file
No application file
Jacob Molnia
commited on
Commit
•
1ee9b02
1
Parent(s):
8b058a4
controller test
Browse files- deployment/.DS_Store +0 -0
- deployment/01_deploy_to_app/.DS_Store +0 -0
- deployment/02_deploy_to_controller/.DS_Store +0 -0
- deployment/02_deploy_to_controller/ansible.cfg +1 -1
- deployment/02_deploy_to_controller/inventory/hosts.ini +1 -1
- deployment/02_deploy_to_controller/playbooks/install_tailscale.yml +0 -30
- deployment/02_deploy_to_controller/playbooks/main.yml +177 -22
- deployment/02_deploy_to_controller/playbooks/setup_ansible.yml +0 -16
- deployment/02_deploy_to_controller/scripts/initial_ssh_config.sh +73 -3
- deployment/02_deploy_to_controller/vars/secrets.yml +31 -9
deployment/.DS_Store
CHANGED
Binary files a/deployment/.DS_Store and b/deployment/.DS_Store differ
|
|
deployment/01_deploy_to_app/.DS_Store
CHANGED
Binary files a/deployment/01_deploy_to_app/.DS_Store and b/deployment/01_deploy_to_app/.DS_Store differ
|
|
deployment/02_deploy_to_controller/.DS_Store
CHANGED
Binary files a/deployment/02_deploy_to_controller/.DS_Store and b/deployment/02_deploy_to_controller/.DS_Store differ
|
|
deployment/02_deploy_to_controller/ansible.cfg
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
[defaults]
|
2 |
inventory = inventory/hosts.ini
|
3 |
remote_user = ubuntu
|
4 |
-
private_key_file =
|
5 |
host_key_checking = False
|
6 |
|
7 |
[privilege_escalation]
|
|
|
1 |
[defaults]
|
2 |
inventory = inventory/hosts.ini
|
3 |
remote_user = ubuntu
|
4 |
+
private_key_file = ../../keys/EC2 instance temp.pem
|
5 |
host_key_checking = False
|
6 |
|
7 |
[privilege_escalation]
|
deployment/02_deploy_to_controller/inventory/hosts.ini
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
[ec2_instance]
|
2 |
-
controler1 ansible_host=
|
|
|
1 |
[ec2_instance]
|
2 |
+
controler1 ansible_host=34.238.170.248
|
deployment/02_deploy_to_controller/playbooks/install_tailscale.yml
DELETED
@@ -1,30 +0,0 @@
|
|
1 |
-
---
|
2 |
-
- name: Install and configure Tailscale
|
3 |
-
hosts: all
|
4 |
-
become: yes
|
5 |
-
vars_files:
|
6 |
-
- ../vars/secrets.yml
|
7 |
-
|
8 |
-
tasks:
|
9 |
-
- name: Add Tailscale GPG key
|
10 |
-
apt_key:
|
11 |
-
url: https://pkgs.tailscale.com/stable/ubuntu/focal.gpg
|
12 |
-
state: present
|
13 |
-
|
14 |
-
- name: Add Tailscale repository
|
15 |
-
apt_repository:
|
16 |
-
repo: deb https://pkgs.tailscale.com/stable/ubuntu focal main
|
17 |
-
state: present
|
18 |
-
filename: tailscale
|
19 |
-
|
20 |
-
- name: Install Tailscale
|
21 |
-
apt:
|
22 |
-
name: tailscale
|
23 |
-
state: present
|
24 |
-
update_cache: yes
|
25 |
-
|
26 |
-
- name: Run tailscale up with pre-authentication
|
27 |
-
command: tailscale up --authkey={{ vault_tailscale_authkey }}
|
28 |
-
register: tailscale_result
|
29 |
-
changed_when: "'Success' in tailscale_result.stdout"
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
deployment/02_deploy_to_controller/playbooks/main.yml
CHANGED
@@ -1,44 +1,199 @@
|
|
1 |
---
|
2 |
-
- name:
|
3 |
-
hosts:
|
4 |
become: yes
|
5 |
vars_files:
|
6 |
- ../vars/secrets.yml
|
7 |
|
8 |
tasks:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
- name: Install Tailscale
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
-
- name:
|
13 |
-
|
|
|
|
|
14 |
|
15 |
-
- name:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
git:
|
17 |
repo: 'https://github.com/jake-molnia/CS_553'
|
18 |
-
dest: /
|
19 |
version: main
|
|
|
20 |
|
21 |
-
- name:
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
-
- name:
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
- name: Copy
|
28 |
copy:
|
29 |
-
|
30 |
-
dest: /home/ubuntu/
|
|
|
|
|
31 |
mode: '0600'
|
|
|
32 |
|
33 |
-
- name:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
command: >
|
35 |
-
|
36 |
-
/home/ubuntu/CS_553/01_deploy_to_app/playbooks/main.yml
|
37 |
-
--vault-password-file /home/ubuntu/vault_password.txt
|
38 |
args:
|
39 |
-
chdir: /
|
|
|
|
|
|
|
40 |
|
41 |
-
- name:
|
42 |
file:
|
43 |
-
path: /home/ubuntu
|
44 |
-
state:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
---
|
2 |
+
- name: Set up Controller Server
|
3 |
+
hosts: all
|
4 |
become: yes
|
5 |
vars_files:
|
6 |
- ../vars/secrets.yml
|
7 |
|
8 |
tasks:
|
9 |
+
- name: Update apt cache
|
10 |
+
apt:
|
11 |
+
update_cache: yes
|
12 |
+
become: yes
|
13 |
+
|
14 |
+
- name: Install required packages
|
15 |
+
apt:
|
16 |
+
name:
|
17 |
+
- apt-transport-https
|
18 |
+
- ca-certificates
|
19 |
+
- curl
|
20 |
+
- gnupg
|
21 |
+
- git
|
22 |
+
- ansible
|
23 |
+
state: present
|
24 |
+
become: yes
|
25 |
+
|
26 |
+
- name: Check if Tailscale GPG key exists
|
27 |
+
stat:
|
28 |
+
path: /usr/share/keyrings/tailscale-archive-keyring.gpg
|
29 |
+
register: tailscale_key
|
30 |
+
|
31 |
+
- name: Download Tailscale GPG key
|
32 |
+
get_url:
|
33 |
+
url: https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg
|
34 |
+
dest: /usr/share/keyrings/tailscale-archive-keyring.gpg
|
35 |
+
mode: '0644'
|
36 |
+
become: yes
|
37 |
+
when: not tailscale_key.stat.exists
|
38 |
+
|
39 |
+
- name: Add Tailscale repository
|
40 |
+
ansible.builtin.apt_repository:
|
41 |
+
repo: deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/ubuntu jammy main
|
42 |
+
state: present
|
43 |
+
filename: tailscale
|
44 |
+
become: yes
|
45 |
+
|
46 |
+
- name: Update apt cache again
|
47 |
+
apt:
|
48 |
+
update_cache: yes
|
49 |
+
become: yes
|
50 |
+
|
51 |
- name: Install Tailscale
|
52 |
+
apt:
|
53 |
+
name: tailscale
|
54 |
+
state: present
|
55 |
+
become: yes
|
56 |
+
|
57 |
+
- name: Check Tailscale status
|
58 |
+
command: tailscale status
|
59 |
+
register: tailscale_status
|
60 |
+
changed_when: false
|
61 |
+
ignore_errors: yes
|
62 |
+
|
63 |
+
- name: Run tailscale up with pre-authentication
|
64 |
+
command: tailscale up --authkey={{ tailscale_authkey }}
|
65 |
+
register: tailscale_result
|
66 |
+
changed_when: "'Success' in tailscale_result.stdout"
|
67 |
+
become: yes
|
68 |
+
when: tailscale_status.rc != 0 or 'Tailscale is stopped' in tailscale_status.stdout
|
69 |
|
70 |
+
- name: Check if repository exists
|
71 |
+
stat:
|
72 |
+
path: /opt/CS_553
|
73 |
+
register: repo_check
|
74 |
|
75 |
+
- name: Remove existing repository if it exists
|
76 |
+
file:
|
77 |
+
path: /opt/CS_553
|
78 |
+
state: absent
|
79 |
+
become: yes
|
80 |
+
when: repo_check.stat.exists
|
81 |
+
|
82 |
+
- name: Clone the Git repository
|
83 |
git:
|
84 |
repo: 'https://github.com/jake-molnia/CS_553'
|
85 |
+
dest: /opt/CS_553
|
86 |
version: main
|
87 |
+
become: yes
|
88 |
|
89 |
+
- name: Set permissions for the cloned repository
|
90 |
+
file:
|
91 |
+
path: /opt/CS_553
|
92 |
+
owner: ubuntu
|
93 |
+
group: ubuntu
|
94 |
+
mode: '0755'
|
95 |
+
recurse: yes
|
96 |
+
become: yes
|
97 |
|
98 |
+
- name: Ensure .ssh directory exists
|
99 |
+
file:
|
100 |
+
path: /home/ubuntu/.ssh
|
101 |
+
state: directory
|
102 |
+
owner: ubuntu
|
103 |
+
group: ubuntu
|
104 |
+
mode: '0700'
|
105 |
+
become: yes
|
106 |
|
107 |
+
- name: Copy ED25519 private SSH key from vault
|
108 |
copy:
|
109 |
+
content: "{{ vault_ssh_private_key }}"
|
110 |
+
dest: /home/ubuntu/.ssh/id_ed25519
|
111 |
+
owner: ubuntu
|
112 |
+
group: ubuntu
|
113 |
mode: '0600'
|
114 |
+
become: yes
|
115 |
|
116 |
+
- name: Ensure correct permissions on ED25519 key
|
117 |
+
file:
|
118 |
+
path: /home/ubuntu/.ssh/id_ed25519
|
119 |
+
owner: ubuntu
|
120 |
+
group: ubuntu
|
121 |
+
mode: '0600'
|
122 |
+
become: yes
|
123 |
+
|
124 |
+
- name: Ensure SSH config file exists
|
125 |
+
file:
|
126 |
+
path: /home/ubuntu/.ssh/config
|
127 |
+
state: touch
|
128 |
+
owner: ubuntu
|
129 |
+
group: ubuntu
|
130 |
+
mode: '0600'
|
131 |
+
become: yes
|
132 |
+
|
133 |
+
- name: Add turing.wpi.edu to SSH config
|
134 |
+
blockinfile:
|
135 |
+
path: /home/ubuntu/.ssh/config
|
136 |
+
block: |
|
137 |
+
Host turing.wpi.edu
|
138 |
+
User jrmolnia
|
139 |
+
Hostname turing.wpi.edu
|
140 |
+
IdentityFile ~/.ssh/id_ed25519
|
141 |
+
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR TURING"
|
142 |
+
become: yes
|
143 |
+
become_user: ubuntu
|
144 |
+
|
145 |
+
- name: Add app server to SSH config
|
146 |
+
blockinfile:
|
147 |
+
path: /home/ubuntu/.ssh/config
|
148 |
+
block: |
|
149 |
+
Host app
|
150 |
+
Port 22018
|
151 |
+
Hostname paffenroth-23.dyn.wpi.edu
|
152 |
+
IdentityFile ~/.ssh/id_ed25519
|
153 |
+
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR APP SERVER"
|
154 |
+
become: yes
|
155 |
+
become_user: ubuntu
|
156 |
+
|
157 |
+
- name: Check if initial setup script has been run
|
158 |
+
stat:
|
159 |
+
path: /home/ubuntu/.initial_setup_complete
|
160 |
+
register: setup_check
|
161 |
+
|
162 |
+
- name: Run initial setup shell script with Tailscale key
|
163 |
command: >
|
164 |
+
/opt/CS_553/deployment/02_deploy_to_controller/scripts/initial_ssh_config.sh -k {{ tailscale_authkey }}
|
|
|
|
|
165 |
args:
|
166 |
+
chdir: /opt/CS_553/deployment/02_deploy_to_controller
|
167 |
+
become: yes
|
168 |
+
become_user: ubuntu
|
169 |
+
when: not setup_check.stat.exists
|
170 |
|
171 |
+
- name: Ensure .ansible directory exists
|
172 |
file:
|
173 |
+
path: /home/ubuntu/.ansible
|
174 |
+
state: directory
|
175 |
+
owner: ubuntu
|
176 |
+
group: ubuntu
|
177 |
+
mode: '0700'
|
178 |
+
become: yes
|
179 |
+
|
180 |
+
- name: Copy vault password file from local machine
|
181 |
+
copy:
|
182 |
+
src: /path/to/local/vault_password.txt
|
183 |
+
dest: /home/ubuntu/.ansible/vault_password.txt
|
184 |
+
owner: ubuntu
|
185 |
+
group: ubuntu
|
186 |
+
mode: '0600'
|
187 |
+
become: yes
|
188 |
+
|
189 |
+
- name: Run Ansible playbook for app server setup
|
190 |
+
command: >
|
191 |
+
ansible-playbook -i inventory/hosts.ini
|
192 |
+
playbooks/main.yml
|
193 |
+
--vault-password-file /home/ubuntu/.ansible/vault_password.txt
|
194 |
+
args:
|
195 |
+
chdir: /opt/CS_553/deployment/01_deploy_to_app
|
196 |
+
become: yes
|
197 |
+
become_user: ubuntu
|
198 |
+
environment:
|
199 |
+
ANSIBLE_CONFIG: /opt/CS_553/deployment/01_deploy_to_app/ansible.cfg
|
deployment/02_deploy_to_controller/playbooks/setup_ansible.yml
DELETED
@@ -1,16 +0,0 @@
|
|
1 |
-
- name: Setup Ansible
|
2 |
-
block:
|
3 |
-
- name: Install Ansible and dependencies
|
4 |
-
apt:
|
5 |
-
name:
|
6 |
-
- ansible
|
7 |
-
- git
|
8 |
-
- python3-pip
|
9 |
-
state: present
|
10 |
-
update_cache: yes
|
11 |
-
- name: Install required Python packages
|
12 |
-
pip:
|
13 |
-
name:
|
14 |
-
- boto3
|
15 |
-
- botocore
|
16 |
-
state: present
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
deployment/02_deploy_to_controller/scripts/initial_ssh_config.sh
CHANGED
@@ -1,5 +1,75 @@
|
|
1 |
#!/bin/bash
|
2 |
-
|
3 |
-
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
EOF
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
#!/bin/bash
|
2 |
+
|
3 |
+
# Function to handle errors
|
4 |
+
handle_error() {
|
5 |
+
echo "Error: $1"
|
6 |
+
exit 1
|
7 |
+
}
|
8 |
+
|
9 |
+
# Function to display usage information
|
10 |
+
usage() {
|
11 |
+
echo "Usage: $0 -k <tailscale_auth_key>"
|
12 |
+
echo " -k Tailscale authentication key"
|
13 |
+
exit 1
|
14 |
+
}
|
15 |
+
|
16 |
+
# Parse command line arguments
|
17 |
+
while getopts "k:" opt; do
|
18 |
+
case $opt in
|
19 |
+
k) TAILSCALE_KEY="$OPTARG" ;;
|
20 |
+
*) usage ;;
|
21 |
+
esac
|
22 |
+
done
|
23 |
+
|
24 |
+
# Check if Tailscale key is provided
|
25 |
+
if [ -z "$TAILSCALE_KEY" ]; then
|
26 |
+
usage
|
27 |
+
fi
|
28 |
+
|
29 |
+
# Function to test SSH connection
|
30 |
+
test_ssh_connection() {
|
31 |
+
ssh -o BatchMode=yes -o ConnectTimeout=5 -J turing.wpi.edu app echo "SSH connection successful" >/dev/null 2>&1
|
32 |
+
}
|
33 |
+
|
34 |
+
# Backup the existing authorized_keys file
|
35 |
+
ssh -i /opt/CS_553/keys/student-admin-key -J turing.wpi.edu app <<EOF || handle_error "Failed to backup authorized_keys"
|
36 |
+
cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak || handle_error "Failed to create backup of authorized_keys"
|
37 |
+
echo "Backup of authorized_keys created"
|
38 |
EOF
|
39 |
+
|
40 |
+
# Update authorized_keys file with the new key while keeping existing keys
|
41 |
+
ssh -i /opt/CS_553/keys/student-admin-key -J turing.wpi.edu app <<EOF || handle_error "Failed to update authorized_keys"
|
42 |
+
NEW_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIARTYgwoPW+VpBofWGYuHIldh18EUo42PHF/e08Dzcyp admin key CS553"
|
43 |
+
if ! grep -q "\$NEW_KEY" ~/.ssh/authorized_keys; then
|
44 |
+
echo "\$NEW_KEY" >> ~/.ssh/authorized_keys || handle_error "Failed to append new key to authorized_keys"
|
45 |
+
fi
|
46 |
+
chmod 600 ~/.ssh/authorized_keys || handle_error "Failed to set permissions on authorized_keys"
|
47 |
+
echo "authorized_keys updated successfully"
|
48 |
+
EOF
|
49 |
+
|
50 |
+
# Test the SSH connection with the new key
|
51 |
+
if test_ssh_connection; then
|
52 |
+
echo "SSH connection with new key successful"
|
53 |
+
else
|
54 |
+
echo "SSH connection with new key failed. Restoring backup..."
|
55 |
+
ssh -i /opt/CS_553/keys/student-admin-key -J turing.wpi.edu app <<EOF || handle_error "Failed to restore authorized_keys backup"
|
56 |
+
cp ~/.ssh/authorized_keys.bak ~/.ssh/authorized_keys || handle_error "Failed to restore backup of authorized_keys"
|
57 |
+
chmod 600 ~/.ssh/authorized_keys || handle_error "Failed to set permissions on restored authorized_keys"
|
58 |
+
echo "Backup of authorized_keys restored"
|
59 |
+
EOF
|
60 |
+
handle_error "SSH connection test failed. Original authorized_keys restored."
|
61 |
+
fi
|
62 |
+
|
63 |
+
# Install Tailscale and set up with provided key
|
64 |
+
ssh -J turing.wpi.edu app <<EOF || handle_error "Failed to set up Tailscale"
|
65 |
+
# Install Tailscale
|
66 |
+
curl -fsSL https://tailscale.com/install.sh | sh || handle_error "Failed to install Tailscale"
|
67 |
+
|
68 |
+
# Run Tailscale with the provided auth key
|
69 |
+
sudo tailscale up --authkey "$TAILSCALE_KEY" || handle_error "Failed to run Tailscale"
|
70 |
+
|
71 |
+
echo "Tailscale setup completed successfully"
|
72 |
+
exit
|
73 |
+
EOF
|
74 |
+
|
75 |
+
echo "Script completed successfully"
|
deployment/02_deploy_to_controller/vars/secrets.yml
CHANGED
@@ -1,10 +1,32 @@
|
|
1 |
$ANSIBLE_VAULT;1.1;AES256
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
$ANSIBLE_VAULT;1.1;AES256
|
2 |
+
32356435633365366531643665366233363439303333336631616536633863623930643832376466
|
3 |
+
3163656465663561656366633633633664373038656437630a373565653666623932343131666163
|
4 |
+
30316135353237633132336334666165623235336466316461636564316139323264333139643539
|
5 |
+
6466356163663936360a336665653638626536636562326532623037393463333264386234323939
|
6 |
+
32613262623131346536363731326431353364393164383163616637373135353730356565623836
|
7 |
+
38363438643131623230343432666133653336626665643365633935383831643635393264633465
|
8 |
+
38363833313166346165616638363430383139356332303139653962643961623266343965383031
|
9 |
+
36306634336132633336323863633136326133336362356365363038366662636232663737363334
|
10 |
+
65633933663334323366333330353538316166373566626535356334306639336339333734666337
|
11 |
+
38386431366661663239366533383732343361323137323235636337316261383536333165633366
|
12 |
+
65333238356638356634303061353733383535636139326134633230313333643639306463373733
|
13 |
+
31316165363230356334316433326538316636656239323662313438306161353462333066396661
|
14 |
+
37383934333265316630663265643862343462643563646663663865666462666632646264346566
|
15 |
+
39633661623434656563376564343165306234626137306431393665376338636339643464653261
|
16 |
+
32616636326161396430633739653232383464656538393434396430366239383963373034363233
|
17 |
+
30303966633363333137303934383038646266326332393630653734613430316433353864303834
|
18 |
+
62353262396138316239326465633638363637326635353261663861373432376364366164623339
|
19 |
+
30363463636266613930333539333761356531316431623161626338313361613833323731353361
|
20 |
+
36383130376335656237353939633136666665636631343961333437333536343131393237643331
|
21 |
+
62623131313437653332346238303361316566313066636439313732633766313930393262666336
|
22 |
+
62616633343138653038626464653466356131323831306461666536643063306461343730343663
|
23 |
+
38383365306331356165343233353865343935323137333236323439343137343834646638356138
|
24 |
+
34636535363861646135326136623661623130336338313735636134656261366631316532333532
|
25 |
+
32626237323233323831376539366433633761653532633838373662366433303265343138636365
|
26 |
+
36393831623836333033343039323836633632623461333730653438366533313564653738383134
|
27 |
+
36353166373239633463333962386235363235633234333361356131323363343439336565623332
|
28 |
+
33613766626365303963376335393962643363383665323032636237643431356435653863373930
|
29 |
+
31373831363366643738623330316261336366666431646632383239613938363239336531343166
|
30 |
+
66396161653265363864323233646139316461646263633764666364313633316465386461663965
|
31 |
+
63343830346436306533343264346238623634616135373037366434613737323137653866653434
|
32 |
+
303136663233333161366664386533316462
|