├── lcget-sh
├── .github
└── FUNDING.yml
├── ChangeLog
├── install.sh
├── lcget
└── README.md
/lcget-sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | expect lcget ${1+"$@"}
3 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | patreon: neurobin
2 | liberapay: neurobin
3 | ko_fi: neurobin
4 | issuehunt: neurobin
5 | open_collective: neurobin
6 | otechie: neurobin
7 |
--------------------------------------------------------------------------------
/ChangeLog:
--------------------------------------------------------------------------------
1 | #ChangeLog:
2 |
3 | ###`0.0.3`: Mon Jun 6 14:08:03 UTC 2016
4 | Changed directory based challenge completion to file based method
5 |
6 | ###`0.0.1`: Sat Jan 16 14:40:52 UTC 2016
7 |
8 | **Happy birth day**
9 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ##We will install to home directory. no need for root privilege
4 | #if [ $EUID -ne 0 ]; then
5 | # echo -e "\n*********This script must be run with root privilege*********"
6 | # echo -e "*******************Sorry! Exiting*************************\n"
7 | # exit 1
8 | #fi
9 |
10 | var=$HOME/bin
11 |
12 | mkdir -p $HOME/bin &&
13 | chmod 755 lcget &&
14 | cp lcget $HOME/bin &&
15 | #Adding $HOME/bin to environment variable
16 | if ! echo $PATH | grep -q ":$var\([/:]\|$\)"; then echo "export PATH=\$PATH:$var" >> ~/.bashrc && . ~/.bashrc ;fi
17 | echo "lcget installed." || {
18 | echo "Failed to install. Abort."; exit 1; }
19 |
20 | echo "Installing dependencies..."
21 |
22 | #Install jssh (required by lcget)
23 | if [ ! -f $HOME/bin/jssh ];then
24 | echo "Installing jssh (ssh wrapper)"
25 | if git clone https://github.com/neurobin/jssh;then
26 | cd jssh &&
27 | chmod 755 jssh &&
28 | cp jssh $HOME/bin &&
29 | echo "Installed jssh successfully." || {
30 | echo "Failed to install jssh. Abort."; exit 1; }
31 | elif wget https://github.com/neurobin/jssh/release.tar.gz;then
32 | #try with wget
33 | tar -xvf jssh-release.tar.gz &&
34 | cd jssh-release &&
35 | chmod 755 jssh &&
36 | cp jssh $HOME/bin &&
37 | echo "Installed jssh successfully." || {
38 | echo "Failed to install jssh. Abort."; exit 1; }
39 | else
40 | echo "
41 | Failed to install jssh. Install it by downloading from
42 | https://github.com/neurobin/jssh
43 | To install, just copy the jssh file to $HOME/bin
44 | and give it execution (755 recommended) permission"
45 | fi
46 | fi
47 | echo "
48 | done.
49 | ***$HOME/bin was added to PATH environment variable.***
50 | To populate it run:
51 | . ~/.bashrc #don't forget the dot (.)
52 | If ~/.bashrc is not respected, then manually add the $HOME/bin
53 | to PATH environment variable."
54 |
55 |
--------------------------------------------------------------------------------
/lcget:
--------------------------------------------------------------------------------
1 | #!/usr/bin/expect --
2 |
3 | #####################################################################
4 | # Coding conventions:
5 | # * Error message must start with 'E: ' (and end with 'Abort.' if it
6 | # needs to be aborted).
7 | #
8 | #####################################################################
9 |
10 | set p_name "lcget"
11 | set p_author "Md. Jahidul Hamid"
12 | set p_author_eu "jahidulhamid"
13 | set p_author_ed "yahoo.com"
14 | set p_version "0.0.3"
15 | set p_source "https://github.com/neurobin/lcget"
16 | set p_bugt "$p_source/issues"
17 | set jssh_link "https://github.com/neurobin/jssh"
18 |
19 | set help "
20 | #####################################################################
21 | # Let's Encrypt wrapper to automate the process of completing
22 | # challenges to get free SSL certificates from Let's Encrypt.
23 | # ###################################################################
24 | # Takes same kind of arguments as the letsencrypt command
25 | # and depends on letsencrypt to run those commands and finally
26 | # Get the certificates. All this script does is to complete the
27 | # challenges using ssh login to remote server.
28 | #
29 | # Usage:
30 | # $p_name \[native and/or letsencrypt options/args]
31 | #
32 | # Native options:
33 | #
34 | # -lp /path/to/letsencrypt/launcher : If this option is not given
35 | # It will assume 'letsencrypt' as the name of the launcher
36 | # and it resides in a path in PATH environment
37 | # variable in your system.
38 | #
39 | # -jp /path/to/jssh : If this option is not given it will be
40 | # assumed that jssh is in a path in PATH environment
41 | # variable in your system i.e 'jssh' command will be
42 | # used by default
43 | #####################################################################
44 | "
45 |
46 | set verinfo "
47 | Name: $p_name
48 | Version: $p_version
49 | Source: $p_source
50 | Bug report: $p_bugt
51 | Author: $p_author
52 |
53 | Author email:
54 | username: $p_author_eu
55 | domain: $p_author_ed
56 | "
57 |
58 | set err_api_change "
59 | It seems Let's Encrypt api has gone through some changes.
60 | Please update this script and if you get this error again,
61 | then please file a bug report at $p_bugt
62 | with all available outputs/logs.
63 | "
64 |
65 |
66 | #####################################################################
67 | proc get_ssh_command_for_http_challenge {dom file_p cont} {
68 | if {$dom == ""} {
69 | puts "E: Couldn't parse domain. Abort."
70 | exit 1
71 | }
72 | if {$file_p == ""} {
73 | puts "E: Couldn't parse directory name. Abort."
74 | exit 1
75 | }
76 | if {$cont == ""} {
77 | puts "E: Couldn't parse content. Abort."
78 | exit 1
79 | }
80 | set cdir [file dirname $file_p]
81 | set comms "echo 'Completing challenge...'
82 | mkdir -p '$cdir' && echo 'Created dir : $cdir'
83 | if printf '%s' '$cont' > '$file_p'; then
84 | echo 'Created file: $file_p'
85 | else
86 | echo 'E: Failed to complete challenge for $dom. Abort.'
87 | exit 1
88 | fi"
89 |
90 | return "$comms"
91 | }
92 |
93 | #####################################################################
94 |
95 |
96 | set timeout -1
97 | #exp_internal 1
98 |
99 | set program "letsencrypt"
100 | set ssh_prog "jssh"
101 | set arguments [lrange $argv 0 end]
102 |
103 | #Check for no-args
104 | if {[llength $argv] == 0} {
105 | puts "
106 | E: No args passed.
107 | Usage: $argv0 subcommand options
108 | Example: $argv0 certonly -c /path/to/config/file
109 | "
110 | exit 1
111 | }
112 |
113 | #$argv 0 can not be empty
114 | if {[lindex $arguments 0] == "" } {
115 | puts "
116 | E: Empty argument.
117 | Usage: $argv0 subcommand options
118 | Example: $argv0 certonly -c /path/to/config/file
119 | "
120 | exit 1
121 | }
122 |
123 |
124 | #Check for -lp option. Set the program path
125 | for {set var 0} {$var<$argc} {incr var} {
126 | if {[lindex $arguments $var] == "-lp" || [lindex $arguments $var] == "--launcher-path"} {
127 | if {[lindex $arguments [expr {$var+1}]] != ""} {
128 | set program [lindex $arguments [expr {$var+1}]]
129 | set arguments [lreplace $arguments $var [expr {$var+1}]]
130 | } else {
131 | puts "E: Argument missing for option: [lindex $arguments $var]"
132 | exit 1
133 | }
134 | }
135 | if {[lindex $arguments $var] == "-jp" || [lindex $arguments $var] == "--jssh-path"} {
136 | if {[lindex $arguments [expr {$var+1}]] != ""} {
137 | set ssh_prog [lindex $arguments [expr {$var+1}]]
138 | set arguments [lreplace $arguments $var [expr {$var+1}]]
139 | } else {
140 | puts "E: Argument missing for option: [lindex $arguments $var]"
141 | exit 1
142 | }
143 | }
144 | if {[lindex $arguments $var] == "-h" || [lindex $arguments $var] == "--help"} {
145 | puts "$help"
146 | }
147 | if {[lindex $arguments $var] == "--version"} {
148 | puts "$verinfo"
149 | }
150 | }
151 |
152 | if {[catch {spawn -noecho $program --text {*}$arguments}]} {
153 | puts "E: Let's Encrypt launcher not found: $program\nYou can specify letsencrypt path with -lp option."
154 | exit 1
155 | }
156 |
157 | set letse_spawn $spawn_id
158 |
159 |
160 | while {1} {
161 | expect {
162 | #set spawn_id $letse_spawn
163 | timeout { exp_send_user "\nE: Failed!!!. Timed out.\n"; exit 1}
164 | eof {break}
165 | -nocase "*http*.well-known*acme-challenge*http*server*configured*continue" {
166 | set output $expect_out(buffer)
167 | set found [regexp {^.*(https?://)([^/]*)/([^[:space:]]*)[^:]*:[[:space:]]*([^[:space:]]*)} $output match protocol domain file_p cont]
168 | if {$found} {
169 | puts "\n\nProtocol: $protocol\nDomain: $domain\nFile: $file_p\nContent: $cont\n"
170 | } else {
171 | puts "\n\nCouldn't get challenge info.$err_api_change\n"
172 | exit 1
173 | }
174 | exp_send_user "Trying to complete challenge for $domain\n\n"
175 | set comms [get_ssh_command_for_http_challenge $domain $file_p $cont]
176 |
177 | set timeout 900
178 | if {[catch {spawn -noecho $ssh_prog -cdw $domain $comms}]} {
179 | puts "E: $ssh_prog command not found.\nIs jssh installed? If not then install it from $jssh_link\nOr if it exists then try giving the path with -jp option."
180 | exit 1
181 | }
182 |
183 | set jssh_spawn $spawn_id
184 |
185 | while {1} {
186 | expect {
187 | timeout { exp_send_user "\nE: Failed!!!. Timed out.\n"; exit 1}
188 | eof {break}
189 | -re "^.\{8,\}$" {#Should be at least 6 in regards of 'ssh: ' for catching unknown prompts
190 | set jssh_output $expect_out(buffer)
191 | #puts $jssh_output
192 | if {[regexp {^.*password.*$} $jssh_output match]} {
193 | stty -echo
194 | exp_send_user -- ""
195 | expect_user -re "(.*)\n"
196 | #exp_send_user "\n"
197 | stty echo
198 | set password $expect_out(1,string)
199 | exp_send "$password\r"
200 | } elseif {[regexp {^E:.*Abort} $jssh_output match]} {
201 | exp_send_user "\nE: Failed to complete challenge for $domain\n"
202 | exit 1
203 | } elseif {[regexp {^.*continue connecting.*[:?][[:space:]]*$} $jssh_output match]} {
204 | exp_send "yes\r"
205 | } elseif {[regexp {^ssh: .*no.*$} $jssh_output match]} {
206 | exp_send_user "\nE: Failed to complete challenge for $domain\n"
207 | exit 1
208 | } elseif {[regexp {^.\{8,\}[:?][[:space:]]*$} $jssh_output match]} {#catching unknown prompts
209 | expect_user -re "(.*)\n"
210 | set password $expect_out(1,string)
211 | exp_send "$password\r"
212 | }
213 | }
214 | }
215 | }
216 | exp_send_user "\nDone for $domain\n"
217 | set timeout -1
218 | if {[catch {exp_close $jssh_spawn}]} {
219 | #spawn was already closed
220 | }
221 | set spawn_id $letse_spawn
222 | exp_send "\r"
223 | }
224 | -nocase "*password" {
225 | stty -echo
226 | exp_send_user -- ""
227 | expect_user -re "(.*)\n"
228 | #exp_send_user "\n"
229 | stty echo
230 | set password $expect_out(1,string)
231 | exp_send "$password\r"
232 | }
233 | -nocase "*terms of service*\n*:" {
234 | exp_send_user -- ""
235 | #expect_user -re "(.*)\n"
236 | #set password $expect_out(1,string)
237 | #exp_send "$password\r"
238 | exp_send "a\r"
239 | #sending a as the answer
240 | }
241 | -nocase "*are you ok with your ip being logged\?*:" {
242 | exp_send_user -- ""
243 | #expect_user -re "(.*)\n"
244 | #set password $expect_out(1,string)
245 | #exp_send "$password\r"
246 | exp_send "y\r"
247 | #sending y as the answer
248 | }
249 | -nocase "*--------------*\n*--------------*:*" {
250 | exp_send_user -- ""
251 | expect_user -re "(.*)\n"
252 | set password $expect_out(1,string)
253 | exp_send "$password\r"
254 | }
255 | -nocase "*--------------*\n*--------------*Press Enter to Continue" {
256 | exp_send_user -- ""
257 | expect_user -re "(.*)\n"
258 | set password $expect_out(1,string)
259 | exp_send "$password\r"
260 | }
261 | }
262 | }
263 |
264 |
265 |
266 | #Clearing step, Finally close the spawns
267 |
268 | #set spawn_id $letse_spawn
269 | if {[catch {exp_close}]} {
270 | #spawn was already closed
271 | }
272 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **lcget** is a wrapper (written in [Tcl/expect](https://en.wikipedia.org/wiki/Expect)) for letsencrypt which automates the task of completing challenges for remote server/domains from a local machine. It relieves you of the pain of running multiple commands in multiple terminals. Most of the time, a single command in a single terminal will be enough to get the certificate from Let's Encrypt. It doesn't require sudo access on remote host if the document root is in /home directory i.e for shared hosting.
2 |
3 | # Mechanism:
4 | **lcget** is an [expect](https://en.wikipedia.org/wiki/Expect) script which runs the letsencrypt command and monitor its' output. When the challenge appears on the output of `letsencrypt` command, the script parses necessary information about the challenge and tries to complete the challenge itself.
5 |
6 | To complete the http challenge in manual mode, **lcget** requires ssh access to the remote host i.e it runs ssh commands to the remote host to meet the necessary requirements for the acme challenge.
7 |
8 | Currently, only the **http challenge in manual mode** is supported.
9 |
10 |
11 | # Dependencies:
12 | The script depends on the following tools/scripts:
13 |
14 | 1. **letsencrypt (certbot):** The letsencrypt tool itself.
15 | 2. **expect:** You may need to install this first if not installed.
16 | 2. **ssh:** It is installed by default in most Unix based system.
17 | 3. **jssh:** It is a wrapper to automate ssh login and/or running ssh commands.
18 |
19 | **To install jssh, download the [jssh script](https://github.com/neurobin/jssh) and put it in a bin directory which is in the PATH environment variable (e.g */usr/bin*)**. The **lcget** script uses `jssh` command to execute it by default. You can run **jssh** from any arbitrary path too; in that case, use the the **lcget** option `-jp` to provide the jssh path. For example:
20 | ```sh
21 | lcget certonly --manual -d example.com -m mymail@example.com -jp /path/to/jssh
22 | ```
23 |
24 | # Install:
25 |
26 | First you will need to give execution permission to the script. An octal `755` permission is recommended.
27 |
28 | * You can run the script with full path or with `./lcget` by `cd`ing into the directory where it resides.
29 | * You can just copy the script into a standard bin directory (e.g */usr/bin*).
30 | * Or you can run the *install.sh* script which tries to install it in *~/bin* along with **jssh**.
31 |
32 | ## Installing examples:
33 |
34 | *Installing in /usr/bin* :
35 |
36 | ```sh
37 | chmod 755 path/to/lcget
38 | sudo cp path/to/lcget /usr/bin
39 | ```
40 | *Installing in ~/bin* :
41 | ```sh
42 | chmod 755 path/to/lcget
43 | cp path/to/lcget $HOME/bin
44 | # Now add $HOME/bin to PATH environment variable if not added already
45 | var=$HOME/bin
46 | if ! echo $PATH | grep -q ":$var\([/:]\|$\)"; then echo "export PATH=\$PATH:$var" >> ~/.bashrc && . ~/.bashrc ;fi
47 | ```
48 | ## Note:
49 | **If the script isn't recognized as an executable by the system**, then you may try the `lcget-sh` script provided. Furthermore, you can change the path of `lcget` to the actual path inside the `lcget-sh` script:
50 | ```sh
51 | #!/bin/sh
52 | expect /actual/path/to/lcget ${1+"$@"}
53 | ```
54 | and install `lcget-sh` instead of `lcget`. In this case, you will be using `lcget-sh` as the **lcget** command.
55 |
56 | **Or** you can try fixing the shebang line (`#!/usr/bin/expect --`) to the correct one for an expect script if it is supported (don't forget the `--` part though).
57 |
58 | # Usage:
59 |
60 | ```
61 | lcget [native or letsencrypt options]
62 | ```
63 | **native options:** These are the options parsed and recognized by lcget. These are:
64 |
65 | * **--launcher-path, -lp :** Launcher path. You can define the letsencrypt launcher path with this option.
66 | * **-jssh-path, -jp :** Arbitrary **jssh** path. If given **jssh** will be run with the full path specified.
67 | * **--help, -h :** This is a mixed option. It will print both **lcget** and **letsencrypt** help.
68 | * **--version:** This is a mixed option. It will print version info for both **lcget** and **letsencrypt**.
69 |
70 | **letsencrypt options:** These are the options recognized by letsencrypt. These options are same as the options supported by the letsencrypt launcher.
71 |
72 |
73 | # How to:
74 | We will need to prepare a **jssh** config file for each of the domains we want to get Let's Encrypt ssl certificate for. We will do this just once, after that we will be running the `lcget` command only.
75 |
76 | ## Create jssh config file:
77 |
78 | The config file must follow the naming convention: **domain.conf** e.g *example.com.conf* for example.com, *www.example.com.conf* for www.example.com etc...
79 |
80 | To create a **jssh config file** run `jssh -aw -c` in a terminal and fill out necessary information. For example:
81 |
82 | ```
83 | ~$ jssh -aw -c
84 |
85 | Give an easy and memorable name to your config file, something like example.com.
86 | Later you will call jssh with this name to login to remote.
87 |
88 | Enter config file name (without .conf):
89 | example.com
90 | Overwrite (y/n)?:
91 | y
92 | Enter domain/IP:
93 | example.com
94 | Enter port number:
95 | 22
96 | Enter username:
97 | neurobin
98 |
99 | If a working directory is specified, jssh -cdw example.com
100 | will run cd WorkDir just after logging in.
101 |
102 | Enter working directory:
103 | $HOME/public_html
104 |
105 | Saved as: /home/user/.neurobin/jssh/example.com.conf
106 | You will call jssh for this configuration like this:
107 | jssh example.com other_ssh_options_or_args
108 | 'jssh example.com' is the native jssh part. All other arguments
109 | will be forwarded to ssh command. Any jssh native option
110 | must be passed before example.com.
111 | You can edit the config file to make further changes.
112 |
113 |
114 | Additional: /home/user/.neurobin/jssh/www.example.com.conf
115 | ```
116 | This will create a config file for *example.com* and also for `www.example.com` with the same configuration ( because of the `-aw` flag passed with jssh).
117 |
118 | **You must give the document root of your domain as the working directory.**
119 |
120 | As *www.example.com* generally points to *example.com* i.e the config for both of them are same, we could create a symbolic link named `www.example.com.conf` too instead of actual file.
121 |
122 | You will need to create **jssh config file** for each of your domains.
123 |
124 | For sub-domains you can just create *subdomain.rootdomain.conf* file with the same credentials as rootdomain except the working directory; working directory must be the document root of the subdomain/domain. In this case ssh will login with the credentials of root domain.
125 |
126 | **Note:**
127 |
128 | * The config file stores username, port, domain name/IP and working directory (in this case document root).
129 |
130 | ## Run lcget and get the certificate:
131 | Now all we have to do is to run the `lcget` command with appropriate options. The following is an example which uses a letsencrypt configuration file (All outputs are shown):
132 |
133 | ```sh
134 | ~$ lcget certonly -c neurobin.ini
135 | Requesting root privileges to run certbot...
136 | /home/user/.local/share/letsencrypt/bin/letsencrypt --text certonly -c neurobin.ini
137 | [sudo] password for user:
138 | Make sure your web server displays the following content at
139 | http://challenge.neurobin.org/.well-known/acme-challenge/s3xMuDO7WwjTUX6pbAq8hj1Ixpf4V-Rin9FBmdHDV14 before continuing:
140 |
141 | s3xMuDO7WwjTUX6pbAq8hj1Ixpf4V-Rin9FBmdHDV14.fl_1v9fRIhdgCXPAMg0ohwMfX66pkSQ_eTJjm2tejZc
142 |
143 | If you don't have HTTP server configured, you can run the following
144 | command on the target server (as root):
145 |
146 | mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
147 | cd /tmp/certbot/public_html
148 | printf "%s" s3xMuDO7WwjTUX6pbAq8hj1Ixpf4V-Rin9FBmdHDV14.fl_1v9fRIhdgCXPAMg0ohwMfX66pkSQ_eTJjm2tejZc > .well-known/acme-challenge/s3xMuDO7WwjTUX6pbAq8hj1Ixpf4V-Rin9FBmdHDV14
149 | # run only once per server:
150 | $(command -v python2 || command -v python2.7 || command -v python2.6) -c \
151 | "import BaseHTTPServer, SimpleHTTPServer; \
152 | s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
153 | s.serve_forever()"
154 | Press ENTER to continue
155 |
156 | Protocol: http://
157 | Domain: challenge.neurobin.org
158 | File: .well-known/acme-challenge/s3xMuDO7WwjTUX6pbAq8hj1Ixpf4V-Rin9FBmdHDV14
159 | Content: s3xMuDO7WwjTUX6pbAq8hj1Ixpf4V-Rin9FBmdHDV14.fl_1v9fRIhdgCXPAMg0ohwMfX66pkSQ_eTJjm2tejZc
160 |
161 | Trying to complete challenge for challenge.neurobin.org
162 |
163 | Completing challenge...
164 | Created dir : .well-known/acme-challenge
165 | Created file: .well-known/acme-challenge/s3xMuDO7WwjTUX6pbAq8hj1Ixpf4V-Rin9FBmdHDV14
166 |
167 | Done for challenge.neurobin.org
168 |
169 | Make sure your web server displays the following content at
170 | http://www.challenge.neurobin.org/.well-known/acme-challenge/DKCumvxBheZMe_cfxA83uhIA7OrTu9RZBdxxaMEbAJ8 before continuing:
171 |
172 | DKCumvxBheZMe_cfxA83uhIA7OrTu9RZBdxxaMEbAJ8.fl_1v9fRIhdgCXPAMg0ohwMfX66pkSQ_eTJjm2tejZc
173 |
174 | If you don't have HTTP server configured, you can run the following
175 | command on the target server (as root):
176 |
177 | mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
178 | cd /tmp/certbot/public_html
179 | printf "%s" DKCumvxBheZMe_cfxA83uhIA7OrTu9RZBdxxaMEbAJ8.fl_1v9fRIhdgCXPAMg0ohwMfX66pkSQ_eTJjm2tejZc > .well-known/acme-challenge/DKCumvxBheZMe_cfxA83uhIA7OrTu9RZBdxxaMEbAJ8
180 | # run only once per server:
181 | $(command -v python2 || command -v python2.7 || command -v python2.6) -c \
182 | "import BaseHTTPServer, SimpleHTTPServer; \
183 | s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
184 | s.serve_forever()"
185 | Press ENTER to continue
186 |
187 | Protocol: http://
188 | Domain: www.challenge.neurobin.org
189 | File: .well-known/acme-challenge/DKCumvxBheZMe_cfxA83uhIA7OrTu9RZBdxxaMEbAJ8
190 | Content: DKCumvxBheZMe_cfxA83uhIA7OrTu9RZBdxxaMEbAJ8.fl_1v9fRIhdgCXPAMg0ohwMfX66pkSQ_eTJjm2tejZc
191 |
192 | Trying to complete challenge for www.challenge.neurobin.org
193 |
194 | Completing challenge...
195 | Created dir : .well-known/acme-challenge
196 | Created file: .well-known/acme-challenge/DKCumvxBheZMe_cfxA83uhIA7OrTu9RZBdxxaMEbAJ8
197 |
198 | Done for www.challenge.neurobin.org
199 |
200 |
201 | IMPORTANT NOTES:
202 | - Congratulations! Your certificate and chain have been saved at
203 | /etc/letsencrypt/live/challenge.neurobin.org/fullchain.pem. Your
204 | cert will expire on 2016-09-04. To obtain a new or tweaked version
205 | of this certificate in the future, simply run letsencrypt again. To
206 | non-interactively renew *all* of your certificates, run
207 | "letsencrypt renew"
208 | - If you like Certbot, please consider supporting our work by:
209 |
210 | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
211 | Donating to EFF: https://eff.org/donate-le
212 |
213 |
214 | ```
215 | The *neurobin.ini* file:
216 |
217 | ```sh
218 | # This is an example of the kind of things you can do in a configuration file.
219 | # All flags used by the client can be configured here. Run Lets Encrypt with
220 | # --help to learn more about the available options.
221 | config-dir = /etc/letsencrypt
222 | work-dir = /home/user/.letsencrypt
223 | logs-dir = /home/user/.letsencrypt
224 | # Use a 4096 bit RSA key instead of 2048
225 | rsa-key-size = 4096
226 |
227 | # Uncomment and update to register with the specified e-mail address
228 | email = admin@neurobin.org
229 |
230 | # Uncomment and update to generate certificates for the specified domains.
231 | #Add subdomains or domains however you like. My recommendation is to put the root domain at beginning.
232 | domains = challenge.neurobin.org, www.challenge.neurobin.org
233 |
234 |
235 | # Uncomment to use a text interface instead of ncurses
236 | # Do not change this
237 | # The expect script works with text interface.
238 | text = True
239 |
240 | # Uncomment to use the standalone authenticator on port 443
241 | # authenticator = standalone
242 | # standalone-supported-challenges = tls-sni-01
243 |
244 | # Uncomment to use the webroot authenticator. Replace webroot-path with the
245 | # path to the public_html / webroot folder being served by your web server.
246 | # authenticator = webroot
247 | # webroot-path = /usr/share/nginx/html
248 |
249 | authenticator = manual
250 | manual-public-ip-logging-ok
251 |
252 |
253 | renew-by-default
254 |
255 | #Testing; comment the following block out when you are done testing and want to get the real thing.
256 | server = https://acme-staging.api.letsencrypt.org/directory
257 | debug
258 | break-my-certs
259 |
260 | #Testing opts end here
261 |
262 | ```
263 |
264 | **Notes:**
265 |
266 | 1. The above gets a test certificate. If you edit and use the above configuration file make sure to comment out the testing block for getting a valid certificate.
267 | 2. In the above example, I didn't have to do anything at all other than running the **lcget** command. Not even giving ssh password as my ssh login uses (private and public) key pairs for authentication.
268 | 3. The above uses **Document Root** of the domain as the challenge directory. If challenge directory is elsewhere, change the jssh config file accordingly, e.g if challenge for example.com is redirected to challenge.example.com, use the document root (or credentials) of `challenge.example.com` as working directory in `example.com.conf` (jssh config file for example.com)
269 |
270 |
271 | # Caveats:
272 |
273 | Only the required codes for completing http challenge in manual mode is included for now, though this can be extended to support other modes and challenges too.
274 |
275 | # Further development:
276 | You can add other options and make **all** the things in letsencrypt automated by a little haggle with Tcl/expect. So, if you feel you can do the development and extend its' capability please fork the repository and add changes and do a pull request. I will greatly appreciate that.
277 |
278 |
--------------------------------------------------------------------------------