Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Is a custom service possible?

    Scheduled Pinned Locked Moved Development
    bootservice startscript
    9 Posts 5 Posters 3.8k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      baketopher
      last edited by

      I'm trying to create a custom service, but I'm getting some errors and don't know if what I'm trying to do is possible with the way pfSense uses rc scripts/services.

      I have this rc.d script "dnscrypt-proxy" in /usr/local/etc/rc.d/

      #!/bin/sh
      
      . /etc/rc.subr
      
      name=dnscrypt-proxy
      rcvar=dnscrypt-proxy_enable
      
      command="/usr/local/bin/${name}"
      pidfile="/var/run/${name}.pid"
      
      load_rc_config "${name}"
      
      : ${dnscrypt-proxy_enable="YES"}
      : ${dnscrypt-proxy_conf="/usr/local/etc/dnscrypt-proxy/${name}.toml"}
      : ${dnsmasq_restart="YES"}
      
      command_args="-config $dnscrypt-proxy_conf -pidfile $pidfile"
      required_files="${dnscrypt-proxy_conf}"
      
      run_rc_command "$1"
      

      but I'm encountering errors like this when using service:

      [2.4.5-RELEASE][admin@pfSense.local]/usr/local/etc/rc.d: service dnscrypt-proxy start
      /usr/local/etc/rc.d/dnscrypt-proxy: WARNING: $dnscrypt-proxy_enable is not set properly - see rc.conf(5).
      Cannot 'start' dnscrypt-proxy. Set dnscrypt-proxy_enable to YES in /etc/rc.conf or use 'onestart' instead of 'start'.
      

      Is there a way to make a custom service like I'm trying to do? My goal is to be able to start/stop/restart dnscrypt without having to reboot pfSense completely. I can can put a simple script in /usr/local/etc/rc.d/ to start dnscrypt proxy successfully on boot, but I'm hoping for a more elegant solution where it can be stopped/started/restarted on the fly if I make config changes or it hangs, etc.

      Thanks for your help!

      1 Reply Last reply Reply Quote 0
      • B
        baketopher
        last edited by

        If I comment out the rcvar line I get a different error:

        #!/bin/sh
        
        . /etc/rc.subr
        
        name=dnscrypt-proxy
        #rcvar=dnscrypt-proxy_enable
        
        command="/usr/local/bin/${name}"
        pidfile="/var/run/${name}.pid"
        
        load_rc_config "${name}"
        
        : ${dnscrypt-proxy_enable="YES"}
        : ${dnscrypt-proxy_conf="/usr/local/etc/dnscrypt-proxy/${name}.toml"}
        : ${dnsmasq_restart="YES"}
        
        command_args="-config $dnscrypt-proxy_conf -pidfile $pidfile"
        required_files="${dnscrypt-proxy_conf}"
        
        run_rc_command "$1"
        

        Error:

        [2.4.5-RELEASE][admin@pfSense.local]/usr/local/etc/rc.d: service dnscrypt-proxy start
        /usr/local/etc/rc.d/dnscrypt-proxy: WARNING: run_rc_command: cannot run -proxy_program
        
        1 Reply Last reply Reply Quote 0
        • stephenw10S
          stephenw10 Netgate Administrator
          last edited by

          pfSense doesn't use the FreeBSD RC system. You would need to create a file like packages do, for example pfBlocker:

          #!/bin/sh
          # This file was automatically generated
          # by the pfSense service handler.
          
          rc_start() {
          	
          	# Check if DNSBL is enabled
          	dnsblcheck="$(/usr/local/sbin/read_xml_tag.sh string installedpackages/pfblockerngdnsblsettings/config/pfb_dnsbl)"
          	if [ "${dnsblcheck}" != 'on' ]; then
          		exit
          	fi
          
          	# Ensure all processes are stopped
          	rc_stop
          
          	# Start DNSBL Lighttpd webserver (Unbound/Python mode) and DNSBL HTTPS Daemon (Unbound mode only)
          	if [ -e '/var/unbound/pfb_dnsbl_lighty.conf' ]; then
          		/usr/bin/logger -p daemon.info -t lighttpd_pfb "[pfBlockerNG] DNSBL Webserver started"
          		/usr/local/sbin/lighttpd_pfb -f /var/unbound/pfb_dnsbl_lighty.conf
          	fi
          
          	# Check if Unbound mode is enabled
          	unbound_mode="$(/usr/local/sbin/read_xml_tag.sh string installedpackages/pfblockerngdnsblsettings/config/dnsbl_mode)"
          
          	# Start DNSBL Resolver queries Daemon
          	if [ "${unbound_mode}" == 'dnsbl_unbound' ]; then
          		/usr/local/bin/php -f /usr/local/pkg/pfblockerng/pfblockerng.inc queries &
          	fi
          
          }
          
          rc_stop() {
          	
          	# Terminate DNSBL Lighttpd webserver, if found
          	pidnum="$(/bin/pgrep lighttpd_pfb)"
          	if [ ! -z "${pidnum}" ]; then
          		/usr/bin/killall lighttpd_pfb
          	fi
          
          	# Terminate DNSBL queries Daemon, if found
          	pidnum="$(/bin/ps -wax | /usr/bin/grep '[p]fblockerng.inc queries' | /usr/bin/awk '{print $1}')"
          	if [ ! -z "${pidnum}" ]; then
          		for i in ${pidnum}; do
          			/bin/kill -9 "${i}"
          		done
          	fi
          
          }
          
          case $1 in
          	start)
          		rc_start
          		;;
          	stop)
          		rc_stop
          		;;
          	restart)
          		rc_stop
          		rc_start
          		;;
          esac
          

          If you want it to appear as a service in the GUI it will need a service section in the config like:

          		<service>
          			<name>pfb_dnsbl</name>
          			<rcfile>pfb_dnsbl.sh</rcfile>
          			<executable>lighttpd_pfb</executable>
          			<description><![CDATA[pfBlockerNG DNSBL service]]></description>
          		</service>
          

          Steve

          B JeGrJ 2 Replies Last reply Reply Quote 1
          • B
            baketopher @stephenw10
            last edited by baketopher

            @stephenw10

            Thanks for the helpful pointers. I managed to get it to work with this dnscrypt-proxy.sh script placed in /usr/local/etc/rc.d:

            #!/bin/sh
            
            name="dnscrypt-proxy"
            conf="/usr/local/etc/dnscrypt-proxy/${name}.toml"
            command="/usr/local/bin/${name}"
            pidfile="/var/run/${name}.pid"
            
            rc_start() {
            	# Check if DNSCrypt is enabled
            	# dnscryptcheck="$(/usr/bin/grep '<pfb_dnsbl>' /conf/config.xml)"
            	# if [ -z "${dnscryptcheck}" ]; then
            		# exit
            	# fi
            	
            	# Make sure all process are stopped
            	rc_stop
            
            	# Start DNSCrypt
            	if [ -f "$conf" ]; then
            		"${command}" -config "${conf}" -pidfile "${pidfile}" &
            		pidnum="$(/bin/pgrep $name)"
            		if [ -n "${pidnum}" ]; then
            			echo "DNSCrypt started (${pidnum})"
            			/usr/bin/logger -p daemon.info -t dnscrypt-proxy "DNSCrypt started"
            		else
            			echo "DNSCrypt failed to start"
            			/usr/bin/logger -p daemon.info -t dnscrypt-proxy "DNSCrypt failed to start"
            		fi
            	else
            		echo "ERROR: $conf does not exist!"
            		/usr/bin/logger -p daemon.info -t dnscrypt-proxy "DNSCrypt failed to start - config file does not exist!"
            		exit 1
            	fi
            }
            
            rc_stop() {	
            	# Terminate DNSCrypt process if found
            	pidnum="$(/bin/pgrep $name)"
            	if [ -n "${pidnum}" ]; then
            		/usr/bin/killall $name
            		echo "DNSCrypt stopped (${pidnum})"
            		/usr/bin/logger -p daemon.info -t dnscrypt-proxy "DNSCrypt stopped"
            	fi
            }
            
            rc_status() {	
            	# Check status and print pid if running
            	pidnum="$(/bin/pgrep $name)"
            	if [ -n "${pidnum}" ]; then
            		echo "DNSCrypt is running (${pidnum})"
            	else
            		echo "DNSCrypt is not running"
            	fi
            }
            
            if [ $# -eq 0 ]; then
            	echo "no parameter specified - starting DNScrypt"
            	rc_start
            	exit
            fi
            
            case $1 in
            	start)
            		rc_start
            		;;
            	stop)
            		rc_stop
            		;;
            	restart)
            		rc_stop
            		rc_start
            		;;
            	status)
            		rc_status
            		;;
            esac
            

            I added these lines to the conf file:

            		<service>
            			<name>dnscrypt</name>
            			<rcfile>dnscrypt-proxy.sh</rcfile>
            			<executable>dnscrypt-proxy</executable>
            			<description><![CDATA[DNS Service]]></description>
            		</service>
            

            Couldn't figure out what the /usr/bin/grep '<pfb_dnsbl>' /conf/config.xml lines were for or how it would relate to my service so I commented them out.

            I'm sure there could be further enhancements for the GUI integration (enabling/disabling/config files) but this will do for now.

            The service now starts on boot and can be restarted/started from the terminal or the UI.

            services.PNG

            Hopefully this helps anybody else trying to do the same thing.

            N 1 Reply Last reply Reply Quote 3
            • JeGrJ
              JeGr LAYER 8 Moderator @stephenw10
              last edited by

              @stephenw10 Perhaps it would be an idea to provide some sort of a "dummy package" with instructions how to create a pfSense package (that could even be submitted via push to netgate or simply used inhouse only) that can be cleanly installed/uninstalled and has some/most hooks/handlers as examples? I don't find the packaging and creation that simple myself so often go the way of small scripts deployed via Filer/Shellcmd pks, but some would perhaps be nice as small simple packages (e.g. custom backup packages for nextcloud or sftp tartgets or the like)?

              Just a proposal :)

              Don't forget to upvote ๐Ÿ‘ those who kindly offered their time and brainpower to help you!

              If you're interested, I'm available to discuss details of German-speaking paid support (for companies) if needed.

              1 Reply Last reply Reply Quote 1
              • stephenw10S
                stephenw10 Netgate Administrator
                last edited by

                It would probably be possible to do that and someone could write up something.

                However we generally discourage people from adding random services to the firewall as it can cause all sorts of issues.
                This would have to be something meant for package development rather than making it easier to run custom services on a one-off basis.

                Steve

                JeGrJ 1 Reply Last reply Reply Quote 0
                • JeGrJ
                  JeGr LAYER 8 Moderator @stephenw10
                  last edited by

                  @stephenw10 said in Is a custom service possible?:

                  This would have to be something meant for package development rather than making it easier to run custom services on a one-off basis.

                  Indeed, that's what I intend as the main purpose. Examples for that would be an Icinga Daemon package (similar to the NRPE package), various Backup solutions (SFTP, GIT based, etc.) that would all spring to my mind that we already did with workarounds like custom scripts and filer/shellcmd help but that would be helpful for all so if it would be easier to start the packaging process and get to know/see the hooks where one could link into pfsense's logic (like config hooks etc.) I think we'd have a chance to get quite a few contributions of really useful packages for all :)

                  Don't forget to upvote ๐Ÿ‘ those who kindly offered their time and brainpower to help you!

                  If you're interested, I'm available to discuss details of German-speaking paid support (for companies) if needed.

                  1 Reply Last reply Reply Quote 0
                  • N
                    networknotwork @baketopher
                    last edited by

                    @baketopher When you say you "added these lines to conf file", which one? The global pfSense conf?

                    GertjanG 1 Reply Last reply Reply Quote 0
                    • GertjanG
                      Gertjan @networknotwork
                      last edited by

                      @networknotwork

                      This one : /conf/config.xml

                      No "help me" PM's please. Use the forum, the community will thank you.
                      Edit : and where are the logs ??

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post
                      Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.