# Renew\_hook in in the /renewal/domain.conf file?

**URL:** <https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900>\
**Category:** Help\
**Created:** [June 28, 2023, 10:28am UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900 "2023-06-28T10:28:22Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thatoo](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/thatoo/32/71605_2.png) [@Thatoo](https://community.letsencrypt.org/u/Thatoo)\
**Post date:** [June 28, 2023, 10:28am UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/1 "2023-06-28T10:28:22Z")

</div>

Hello,

I have an executable letsencrypt.sh file containing command line to send the fullchain.pem file by ssh :

```plaintext
root@aaa:~# cat /root/letsencrypt.sh 
sftp -P zzz sftpuser@xxx.xxx.xxx.xxx:letsencrypt <<< $'put /etc/letsencrypt/live/my.domain/fullchain.pem'

```

If I execute this .sh file `root@aaa:~# ./letsencrypt.sh` or `root@aaa:~# /root/letsencrypt.sh` it does the job.

Now I want that script to be executed everytime certbot renew the letsencrypt certificate so I added the following line in the file /etc/letsencrypt/renewal/my.domain.conf :  
`renew_hook = /root/letsencrypt.sh`

Unfortunatly, it doesn't work. When I look at logs just after the renewal of the letsencrypt certificate by certbot, I find :

```plaintext
2023-06-24 21:50:02,334:DEBUG:certbot._internal.storage:Writing new config /etc/letsencrypt/renewal/my.domain.conf.new.
2023-06-24 21:50:02,335:INFO:certbot.compat.misc:Running deploy-hook command: /root/letsencrypt.sh
2023-06-24 21:50:02,340:ERROR:certbot.compat.misc:deploy-hook command "/root/letsencrypt.sh" returned error code 2
2023-06-24 21:50:02,340:ERROR:certbot.compat.misc:Error output from deploy-hook command letsencrypt.sh:
/root/letsencrypt.sh: 1: Syntax error: redirection unexpected

```

Does anyone know why it doesn't work?, what does mean this "Syntax error: redirection unexpected" error?

---

<div class="post-metadata">

**Author:** ![Nekit](https://avatars.discourse-cdn.com/v4/letter/n/7feea3/32.png) [@Nekit](https://community.letsencrypt.org/u/Nekit)\
**Post date:** [June 28, 2023, 10:48am UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/2 "2023-06-28T10:48:25Z")

</div>

[This stackoverflow answer](https://stackoverflow.com/a/2462357) suggests specifying a shebang line.

---

<div class="post-metadata">

**Author:** ![Thatoo](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/thatoo/32/71605_2.png) [@Thatoo](https://community.letsencrypt.org/u/Thatoo)\
**Post date:** [June 28, 2023, 1:09pm UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/3 "2023-06-28T13:09:26Z")

</div>

I'll try, check if it works for the next renewal which is supposed to happen tonight and let you know if that solve the problem.  
I also change  
`renew_hook = /root/letsencrypt.sh`  
into  
`renew_hook = bash /root/letsencrypt.sh`

---

<div class="post-metadata">

**Author:** ![MikeMcQ](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/mikemcq/32/52772_2.png) [@MikeMcQ](https://community.letsencrypt.org/u/MikeMcQ)\
**Post date:** [June 28, 2023, 1:37pm UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/4 "2023-06-28T13:37:05Z")

</div>

You can test a deploy hook any time like this:

```nohighlight
certbot renew --dry-run --run-deploy-hooks

```

> --run-deploy-hooks
> 
> When performing a test run using `--dry-run` or `reconfigure`, run any applicable deploy hooks. This includes hooks set on the command line, saved in the certificate's renewal configuration file, or present in the renewal-hooks directory. To exclude directory hooks, use --no-directory-hooks. The hook(s) will only be run if the dry run succeeds, and will use the current active certificate, not the temporary test certificate acquired during the dry run.

---

<div class="post-metadata">

**Author:** ![rg305](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/rg305/32/91314_2.png) [@rg305](https://community.letsencrypt.org/u/rg305)\
**Post date:** [June 28, 2023, 2:03pm UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/5 "2023-06-28T14:03:09Z")

</div>

> [@Thatoo](#):
>
> `bash`

I find it best practice to always spell out the entire path, like:  
`/bin/bash`

---

<div class="post-metadata">

**Author:** ![Osiris](https://avatars.discourse-cdn.com/v4/letter/o/839c29/32.png) [@Osiris](https://community.letsencrypt.org/u/Osiris)\
**Post date:** [June 28, 2023, 5:26pm UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/6 "2023-06-28T17:26:57Z")

</div>

What's the purpose of that `put` command? My bash doesn't recognise it, I don't have it installed on my Linux and I personally don't know it.

---

<div class="post-metadata">

**Author:** ![rg305](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/rg305/32/91314_2.png) [@rg305](https://community.letsencrypt.org/u/rg305)\
**Post date:** [June 28, 2023, 6:11pm UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/7 "2023-06-28T18:11:51Z")

</div>

@Osiris, `put` is an FTP command - used to upload a file [`get` is used to download]

---

<div class="post-metadata">

**Author:** ![Rip](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/rip/32/70863_2.png) [@Rip](https://community.letsencrypt.org/u/Rip)\
**Post date:** [June 28, 2023, 9:52pm UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/8 "2023-06-28T21:52:27Z")

</div>

I dunno guys... I'd simplify it a bit: (requires ssh key access)  
Secure copy is easier to wrap your head around than secure ftp. Assuming sftp is not the only means of access.

```plaintext

scp -p -P "$DEST_PORT" /etc/letsencrypt/live/my.domain/fullchain.pem' root@"$DEST_SERVER":/path/to/where/you/want/it/to/go/fullchain.pem
-p = preserve attributes
-P "$DEST_PORT" = replace with your destination port (hopefully not 22) 
root@"$DEST_SERVER" = USER@my.domain

```

My 2 cents

---

<div class="post-metadata">

**Author:** ![Thatoo](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/thatoo/32/71605_2.png) [@Thatoo](https://community.letsencrypt.org/u/Thatoo)\
**Post date:** [June 29, 2023, 9:57am UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/9 "2023-06-29T09:57:42Z")

</div>

root@aaa:~# cat /root/letsencrypt.sh

```plaintext
#!/bin/bash
sftp -P zzz sftpuser@xxx.xxx.xxx.xxx:letsencrypt <<< $'put /etc/letsencrypt/live/my.domain/fullchain.pem'

```

and adding at the end of `/etc/letsencrypt/renewal/my.domain.conf` the line  
`post_hook = bash /root/letsencrypt.sh`

it works!!!

Next question.

Is it better to write

`post_hook = bash /root/letsencrypt.sh`  
or  
`renew_hook = bash /root/letsencrypt.sh`

I guess I'll write `/bin/bash` instead of `bash` indeed to make it best practice then.

---

<div class="post-metadata">

**Author:** ![Thatoo](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/thatoo/32/71605_2.png) [@Thatoo](https://community.letsencrypt.org/u/Thatoo)\
**Post date:** [June 29, 2023, 10:09am UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/10 "2023-06-29T10:09:58Z")

</div>

Why is scp better than sftp?

For security reason, I limited the use of ssh only to sftp but I don't know if it's a good idea.

---

<div class="post-metadata">

**Author:** ![Nekit](https://avatars.discourse-cdn.com/v4/letter/n/7feea3/32.png) [@Nekit](https://community.letsencrypt.org/u/Nekit)\
**Post date:** [June 29, 2023, 10:12am UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/11 "2023-06-29T10:12:53Z")

</div>

`post_hook` runs on _every_ `certbot renew` invocation regardless whether or not the certificate was _actually_ renewed. `renew_hook` runs _only_ when there was a _successful_ renewal.

---

<div class="post-metadata">

**Author:** ![Rip](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/rip/32/70863_2.png) [@Rip](https://community.letsencrypt.org/u/Rip)\
**Post date:** [June 29, 2023, 2:13pm UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/12 "2023-06-29T14:13:45Z")

</div>

Just offering an alternative for you. It is your choice to use whatever works and is comfortable for you.🙂

---

<div class="post-metadata">

**Author:** ![Thatoo](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/thatoo/32/71605_2.png) [@Thatoo](https://community.letsencrypt.org/u/Thatoo)\
**Post date:** [July 3, 2023, 9:37am UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/13 "2023-07-03T09:37:32Z")

</div>

So, to summarize, the solution is

```plaintext
root@aaa:~# cat /root/letsencrypt.sh
#!/bin/bash
sftp -P zzz sftpuser@xxx.xxx.xxx.xxx:letsencrypt <<< $'put /etc/letsencrypt/live/my.domain/fullchain.pem'

```

and top add the following line in the file `/etc/letsencrypt/renewal/my.domain.conf` :  
`renew_hook = bash /root/letsencrypt.sh`

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/letsencrypt/original/3X/c/a/ca6c06ea1ea201324bba7048c6841ce60236468d.png) [@system](https://community.letsencrypt.org/u/system)\
**Post date:** [August 2, 2023, 9:37am UTC](https://community.letsencrypt.org/t/renew-hook-in-in-the-renewal-domain-conf-file/200900/14 "2023-08-02T09:37:52Z")

</div>

Closed on August 2, 2023, 9:37am UTC

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
