Juniper Open Learning: Using EVE-NG with Juniper Topologies – Slides

Since so many of you asked for it: Of course I can share the Slides πŸ™‚

Here you find the Slides from the Session held on 15.09.2020

Adding IPv6 to your PfSense OpenVPN to access IPv6 content in IPv4-only networks

Yesterday I played with the OpenVPN Settings in my PfSense at home and thought:
Will it be possible to enable IPv6 through my VPN so that I can access my IPv6 only Content even when I’m staying at my parents-in-law where I only have a crappy 1&1 IPv4 DSL?
Turns out: HELL YEAH πŸ˜€

This was way easier than I thought, but I thought I share it with you.
This article is based on the following assumptions:
– You already have your OpenVPN running over IPv4
– Your Server has connection over IPv4 and IPv6 (basically, you are dual-homed so that the Server can access the content and serve it to you)
– You have a free /64 Subnet for your clients to use that is routed towards your Server’s GW IP

Start by navigating to VPN –> OpenVPN. Next to the “Server,” hit the Edit button.
You should now see a similar screen to the one below:

You can leave the Protocol to IPv4 only. I want my Clients to have IPv6 Access everywhere. Enabling the Protocol for both IP-Families does not make sense to me. If I have v6 connectivity already, I can surf away – this only makes sense if you also want to connect via IPv6 in IPv6-only networks but still get your IPv6 Prefix due to ACLs and such.

If you scroll down, you see the IPv6-Tunnel-Network. Insert your /64 prefix in there. PfSense will take care of the Rest for you (DHCPv6, Gateway creation, and so on) so that your clients know how to reach the IPv6 World and get an IPv6 address from your subnet. I also ticked “force all Traffic through the tunnel.” If you don’t check this box, your Client will get an IPv6 Address assigned and will then try to talk IPv6 directly (which will fail in IPv4-only networks obviously) to the resources out there.

You want to make sure, that your Clients are able to resolve IPv6 FQDN’s so don’t forget to add at least one IPv6 Nameserver IP to your DNS Section of the Settings.

If you scroll down a little further, you will see the “Gateway creation” section. Initially, mine was set to IPv4 only – change this to “Both” so that PfSense automatically creates the Gateways for you. You can do that manually, but why make life harder than it needs to be? IPv6 is straightforward – and we should leave it this way πŸ™‚

Hit the “Safe” Button and that’s basically it.

At least I thought… πŸ˜‰

Remember: You just enabled IPv6 for your Tunnel, but your Client is still using the old config-file for IPv4 only!
So either go to the “Client Export” Section and download the new config file or add this to your current config:

tun-ipv6

I added it just below the IPv4 tun mode so my file begins with:

dev tun
tun-ipv6
...
...
...

That’s it. Connect to your Server again and BAM – IPv6 tunneled through IPv4 πŸ™‚
Hope this helps you to enjoy IPv6 everywhere!

Juniper Open Learning: Technical Series Using EVE-NG with Juniper Topologies

On September 15th 2020 I will host another session with the amazing @JuniperCertify team about EVE-NG and Juniper devices.
Reserve your seat here: https://learningportal.juniper.net/juniper/user_activity_schedule_info.aspx?id=157373&activity=11495

Topics are:
EVE-NG in IPv6-only mode
Creating Custom Templates (vSRX 3.0, JunOS Space Policy Enforcer, etc.) [Live-Demo]
Tips, tricks, and new features [Live-Demo]
Questions and Answers

Whether you are new to Juniper and EVE-NG or already a veteran – I’m sure you will learn something in the session πŸ™‚ If you have questions, feel free bring them to the session.

Looking forward to a great session with the most amazing community πŸ™‚

Create a config export script for the vSRX 3.0 template

Some time ago I blogged about a custom template for the vSRX 3.0. One drawback was, that the config-export would no longer work, since this is a custom template but I took this drawback because the speed improvements were very good and I usually export my config manually. But I understand, that some of you use this feature in and out so I tried to generate a config-export-script. With the help of Alain from EVE-NG I was able to map the config-script to the new template πŸ™‚ Huge thanks to Alain πŸ™‚

Here’s what you need to do:

1.) Copy this script with the name config_vsrx30.py to /opt/unetlab/scripts/ – here’s my script, that will use the username ‘root’ and the password ‘Juniper’:

#!/usr/bin/env python3

# scripts/config_vsrx30.py
#
# Import/Export script for vsrx30.
#
# @author Andrea Dainese <andrea.dainese@gmail.com>
# @author Alain Degreffe <eczema@ecze.com>
# @copyright 2014-2016 Andrea Dainese
# @copyright 2017-2018 Alain Degreffe
# @copyright 2019-2020 Christian Scholz
# @license BSD-3-Clause https://github.com/dainok/unetlab/blob/master/LICENSE
# @link http://www.eve-ng.net/
# @version 20200422

import getopt, multiprocessing, os, pexpect, re, sys, time

username = 'root'
password = 'Juniper'
conntimeout = 3     # Maximum time for console connection
expctimeout = 3     # Maximum time for each short expect
longtimeout = 30    # Maximum time for each long expect
timeout = 60        # Maximum run time (conntimeout is included)

def node_login(handler):
    # Send an empty line, and wait for the login prompt
    i = -1
    while i == -1:
        try:
            handler.sendline('\r\n')
            i = handler.expect([
                'login:',
                'root@.*%',
                'root>',
                'root@.*>',
                'root#',
                'root@.*#'], timeout = 5)
        except:
            i = -1

    if i == 0:
        # Need to send username and password
        handler.sendline(username)
        try:
            j = handler.expect(['root@.*#', 'Password:'], timeout = longtimeout)
        except:
            print('ERROR: error waiting for ["root@.*%", "password:"] prompt.')
            node_quit(handler)
            return False

        if j == 0:
            # Nothing to do
            return True
        elif j == 1:
            handler.sendline(password)
            try:
                handler.expect('root@.*#', timeout = longtimeout)
            except:
                print('ERROR: error waiting for "root@.*%" prompt.')
                node_quit(handler)
                return False
            return True
        else:
            # Unexpected output
            node_quit(handler)
            return False
    elif i == 1:
        # Nothing to do
        return True
    elif i == 2 or i == 3:
        # Exit from CLI mode
        handler.sendline('exit')
        try:
            handler.expect('root@.*%', timeout = expctimeout)
        except:
            print('ERROR: error waiting for "root@.*%" prompt.')
            node_quit(handler)
            return False
        return True
    elif i == 4:
        # Exit from configuration mode
        handler.sendline('exit')
        try:
            handler.expect(['root>', 'root@.*>'], timeout = expctimeout)
        except:
            print('ERROR: error waiting for ["root>", "root@.*>"] prompt.')
            node_quit(handler)
            return False
        # Exit from CLI mode
        handler.sendline('exit')
        try:
            handler.expect('root.*%', timeout = expctimeout)
        except:
            print('ERROR: error waiting for "root@.*%" prompt.')
            node_quit(handler)
            return False
        return True
    elif i == 5:
        return True
    else:
        # Unexpected output
        node_quit(handler)
        return False

def node_quit(handler):
    if handler.isalive() == True:
        handler.sendline('exit\n')
    handler.close()

def config_get(handler):
    # Clearing all "expect" buffer
    while True:
        try:
            handler.expect('root@.*#', timeout = 0.1)
        except:
            break

    # Go into CLI mode
    handler.sendline('cli')
    try:
        handler.expect(['root>', 'root@.*>'], timeout = longtimeout)
    except:
        print('ERROR: error waiting for ["root>", "root@.*>"] prompt.')
        node_quit(handler)
        return False

    # Disable paging
    handler.sendline('set cli screen-length 0')
    try:
        handler.expect(['root>', 'root@.*>'], timeout = longtimeout)
    except:
        print('ERROR: error waiting for ["root>", "root@.*>"] prompt.')
        node_quit(handler)
        return False

    # Getting the config
    handler.sendline('show configuration | display set')
    try:
        handler.expect(['root>', 'root@.*>'], timeout = longtimeout)
    except:
        print('ERROR: error waiting for ["root>", "root@.*>"] prompt.')
        node_quit(handler)
        return False

    config = handler.before.decode()

    # Exit from config mode
    handler.sendline('exit')
    try:
        handler.expect('root@.*#', timeout = longtimeout)
    except:
        print('ERROR: error waiting for "root@.*%" prompt.')
        node_quit(handler)
        return False
    
    # Manipulating the config
    config = re.sub('\r', '', config, flags=re.DOTALL)                                      # Unix style
    config = re.sub('.*show configuration \| display set', '', config, flags=re.DOTALL)          # Header
    config = re.sub('\nroot.*>.*', '\n', config, flags=re.DOTALL)                        # Footer

    return config

def config_put(handler, config):
    # mount drive
    handler.sendline('mount -t cd9660 /dev/cd0 /mnt')
    try:
        handler.expect(['root>', 'root@.*#'], timeout = expctimeout)
    except:
        print('ERROR: error waiting for ["root>", "root@.*%"] prompt.')
        node_quit(handler)
        return False

    # Go into CLI mode
    handler.sendline('cli')
    try:
        handler.expect(['root>', 'root@.*>'], timeout = longtimeout)
    except:
        print('ERROR: error waiting for ["root>", "root@.*>"] prompt.')
        node_quit(handler)
        return False

    # Got to configure mode
    handler.sendline('configure')
    try:
        handler.expect(['root#', 'root@.*#'], timeout = longtimeout)
    except:
        print('ERROR: error waiting for ["root#", "root@.*#"] prompt.')
        node_quit(handler)
        return False

    # Start the load mode
    handler.sendline('load set /mnt/juniper.conf')
    try:
        handler.expect('load complete', timeout = longtimeout)
    except:
        print('ERROR: error waiting for "load complete" prompt.')
        node_quit(handler)
        return False

    # Save
    handler.sendline('commit')
    try:
        handler.expect(['root#', 'root@.*#'], timeout = longtimeout)
    except:
        print('ERROR: error waiting for ["root#", "root@.*#"] prompt.')
        node_quit(handler)
        return False

    handler.sendline('exit')
    try:
        handler.expect(['root>', 'root@.*>'], timeout = longtimeout)
    except:
        print('ERROR: error waiting for ["root>", "root@.*>"] prompt.')
        node_quit(handler)
        return False

    return True

def usage():
    print('Usage: %s <standard options>' %(sys.argv[0]));
    print('Standard Options:');
    print('-a <s>    *Action can be:')
    print('           - get: get the startup-configuration and push it to a file')
    print('           - put: put the file as startup-configuration')
    print('-f <s>    *File');
    print('-p <n>    *Console port');
    print('-t <n>     Timeout (default = %i)' %(timeout));
    print('* Mandatory option')

def now():
    # Return current UNIX time in milliseconds
    return int(round(time.time() * 1000))

def main(action, fiename, port):
    try:
        # Connect to the device
        tmp = conntimeout
        while (tmp > 0):
            handler = pexpect.spawn('telnet 127.0.0.1 %i' %(port))
            time.sleep(0.1)
            tmp = tmp - 0.1
            if handler.isalive() == True:
                break

        if (handler.isalive() != True):
            print('ERROR: cannot connect to port "%i".' %(port))
            node_quit(handler)
            sys.exit(1)

        # Login to the device and get a privileged prompt
        rc = node_login(handler)
        if rc != True:
            print('ERROR: failed to login.')
            node_quit(handler)
            sys.exit(1)

        if action == 'get':
            config = config_get(handler)
            if config in [False, None]:
                print('ERROR: failed to retrieve config.')
                node_quit(handler)
                sys.exit(1)

            try:
                fd = open(filename, 'a')
                fd.write(config)
                fd.close()
            except:
                print('ERROR: cannot write config to file.')
                node_quit(handler)
                sys.exit(1)
        elif action == 'put':
            try:
                fd = open(filename, 'r')
                config = fd.read()
                fd.close()
            except:
                print('ERROR: cannot read config from file.')
                node_quit(handler)
                sys.exit(1)

            rc = config_put(handler, config)
            if rc != True:
                print('ERROR: failed to push config.')
                node_quit(handler)
                sys.exit(1)

            # Remove lock file
            lock = '%s/.lock' %(os.path.dirname(filename))

            if os.path.exists(lock):
                os.remove(lock)

            # Mark as configured
            configured = '%s/.configured' %(os.path.dirname(filename))
            if not os.path.exists(configured):
                open(configured, 'a').close()

        node_quit(handler)
        sys.exit(0)

    except Exception as e:
        print('ERROR: got an exception')
        print(type(e))  # the exception instance
        print(e.args)   # arguments stored in .args
        print(e)        # __str__ allows args to be printed directly,
        node_quit(handler)
        return False

if __name__ == "__main__":
    action = None
    filename = None
    port = None

    # Getting parameters from command line
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'a:p:t:f:', ['action=', 'port=', 'timeout=', 'file='])
    except getopt.GetoptError as e:
        usage()
        sys.exit(3)

    for o, a in opts:
        if o in ('-a', '--action'):
            action = a
        elif o in ('-f', '--file'):
            filename = a
        elif o in ('-p', '--port'):
            try:
                port = int(a)
            except:
                port = -1
        elif o in ('-t', '--timeout'):
            try:
                timeout = int(a) * 1000
            except:
                timeout = -1
        else:
            print('ERROR: invalid parameter.')

    # Checking mandatory parameters
    if action == None or port == None or filename == None:
        usage()
        print('ERROR: missing mandatory parameters.')
        sys.exit(1)
    if action not in ['get', 'put']:
        usage()
        print('ERROR: invalid action.')
        sys.exit(1)
    if timeout < 0:
        usage()
        print('ERROR: timeout must be 0 or higher.')
        sys.exit(1)
    if port < 0:
        usage()
        print('ERROR: port must be 32768 or higher.')
        sys.exit(1)
    if action == 'get' and os.path.exists(filename):
        usage()
        print('ERROR: destination file already exists.')
        sys.exit(1)
    if action == 'put' and not os.path.exists(filename):
        usage()
        print('ERROR: source file does not already exist.')
        sys.exit(1)
    if action == 'put':
        try:
            fd = open(filename, 'r')
            config = fd.read()
            fd.close()
        except:
            usage()
            print('ERROR: cannot read from file.')
            sys.exit(1)

    # Backgrounding the script
    end_before = now() + timeout
    p = multiprocessing.Process(target=main, name="Main", args=(action, filename, port))
    p.start()

    while (p.is_alive() and now() < end_before):
        # Waiting for the child process to end
        time.sleep(1)

    if p.is_alive():
        # Timeout occurred
        print('ERROR: timeout occurred.')
        p.terminate()
        sys.exit(127)

    if p.exitcode != 0:
        sys.exit(127)

    sys.exit(0)

Now that we have our python script under /opt/unetlab/scripts/config_vsrx30.py we need to add a line to our vSRX 3.0 template located at /opt/unetlab/html/templates/intel/vsrx30.yml

# Copyright (c) 2016, Andrea Dainese
# Copyright (c) 2016, Alain Degreffe
# Copyright (c) 2017, Alain Degreffe
# Copyright (c) 2019, Christian Scholz
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the UNetLab Ltd nor  the name of EVE-NG Ltd nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---
type: qemu
name: vSRX3-0
config_script: config_vsrx30.py
cpulimit: 1
icon: JuniperSRX.png
cpu: 2
ram: 4096
eth_name:
- fxp0/mgmt
eth_format: ge-0/0/{0}
ethernet: 6
qemu_nic: virtio-net-pci
console: telnet
qemu_arch: x86_64
qemu_options: -machine type=pc-1.0,accel=kvm -cpu qemu64,+ssse3,+sse4.1,+sse4.2,+x2apic,+aes,pclmulqdq  -serial
  mon:stdio -nographic   -nodefconfig -nodefaults -rtc base=utc
...

As you can see, the line “config_script: config_vsrx30.py” has been added, so that the server knows, what script to trigger when using the vSRX3.0 template. After I added this line and saved it, I could immediately export without having to reboot the server or wipe a device πŸ™‚

As you can see, it’s now possible to export your vSRX3.0 configs even with the custom template πŸ™‚ Enjoy!

Keeping the Network Up and Running During the COVID-19 Era (A Virtual Panel with Networking Experts)

Last week I blogged about the virtual Roundtable that we had to discuss our work in the Corona Era.

I promised you to share this exciting talk – huge shoutouts to the Team and to Mike for hosting us – this was one of the best sessions we did so far and I enjoyed it a lot πŸ™‚ Below you find the description and the Video:

The COVID-19 pandemic is putting unprecedented strain on not only our way of living but our networks as well. Juniper Networks’ CMO, Mike Marcellin, and networking experts from several Juniper customers and partners recently met to discuss what they’re experiencing on the front lines of IT and share advice as we navigate the path forward. For more advice and discussions with our IT community, please visit Real Talk: The Network Matters, a forum dedicated to sharing advice, strategies and workarounds that everyone can use: https://forums.juniper.net/t5/Real-Ta…

And a big thank you to our panel of experts:
Andrew Alston, Group Head of IP Strategy, Liquid Telecommunications
Paul Clarke, Customer Solutions Architect, Fujitsu
Tom Dwyer, Principal Engineer, Nexus
Stefan Fouant, CTO, ShortestPathFirst
Chris Parker, Senior Network Engineer, Nominet
Nick Ryce, Senior Network Architect, Commsworld
Christian Scholz, Senior Consultant Network & Security, Telonic

EVE-NG export config with custom password

If you use the “config export” in your EVE-NG you might have noticed, that there are predefined passwords, that you have to use for this task.
If you want to change that, you can do this by modifying the files in /opt/unetlab/scripts/

You will find the vsrxng, vmx (both flavors), vQFX and others here – modify the “password” to your needs (Juniper, password1 and such).

Hope this helps you πŸ™‚

Monitor your EVE-NG Server via snmp (IPv6 only EVE)

I like the idea of monitoring my EVE-NG Server with my external LibreNMS Server. Setting this up on EVE-NG (Ubuntu 16.04) is relatively easy – even in IPv6 only mode. You just need to install snmpd (apt install snmpd).
However, the description inside the main file is completely wrong for ipv6 in my opinion and you should be aware of that because this is a small detail, that you might miss (I did…).

WARNING: It will discover a freakin LOT of Interfaces – every point-to-point bridge in the background, every little connection will be discovered and monitored by LibreNMS πŸ˜€ So be careful – you might kill your box when running large labs…

In the file /etc/snmp/snmpd.conf the team behind the snmpd made a, in my opinion, terrible mistake.

Per default, it listens on udp:161 (so basically EVERY IPv4 Address which is fine, since you should have a firewall in front of your host – different topic…) but just on udp6[::1]:161 which in the IPv4 world would be just 127.0.0.1 – FATAL if you ask me, especially because they state “listen for connections on ALL interfaces” which is clearly wrong. Seems like IPv6 is indeed new even for some senior developers πŸ˜‰

Here’s my working file (just change public to your desired string and allow snmp through your ipv6 capable firewall):

###############################################################################
#
# EXAMPLE.conf:
#   An example configuration file for configuring the Net-SNMP agent ('snmpd')
#   See the 'snmpd.conf(5)' man page for details
#
#  Some entries are deliberately commented out, and will need to be explicitly activated
#
###############################################################################
#
#  AGENT BEHAVIOUR
#

#  Listen for connections from the local system only
#  Listen for connections on all interfaces (both IPv4 *and* IPv6)
# agentAddress udp:161,udp6:[::1]:161 - commented out because of classic bs, see correct line below

agentAddress udp:161,udp6:161




###############################################################################
#
#  SNMPv3 AUTHENTICATION
#
#  Note that these particular settings don't actually belong here.
#  They should be copied to the file /var/lib/snmp/snmpd.conf
#     and the passwords changed, before being uncommented in that file *only*.
#  Then restart the agent

#  createUser authOnlyUser  MD5 "remember to change this password"
#  createUser authPrivUser  SHA "remember to change this one too"  DES
#  createUser internalUser  MD5 "this is only ever used internally, but still change the password"

#  If you also change the usernames (which might be sensible),
#  then remember to update the other occurances in this example config file to match.



###############################################################################
#
#  ACCESS CONTROL
#

                                                 #  system + hrSystem groups only
view   systemonly  included   .1.3.6.1.2.1.1
view   systemonly  included   .1.3.6.1.2.1.25.1

#view   all         included   .1                80



#rocommunity public default    -V all
rocommunity6 public 




                                                 #  Full access from an example network
                                                 #     Adjust this network address to match your local
                                                 #     settings, change the community string,
                                                 #     and check the 'agentAddress' setting above

                                                 #  Full read-only access for SNMPv3
# rouser   authOnlyUser
                                                 #  Full write access for encrypted requests
                                                 #     Remember to activate the 'createUser' lines above
#rwuser   authPrivUser   priv

#  It's no longer typically necessary to use the full 'com2sec/group/access' configuration
#  r[ow]user and r[ow]community, together with suitable views, should cover most requirements



###############################################################################
#
#  SYSTEM INFORMATION
#

#  Note that setting these values here, results in the corresponding MIB objects being 'read-only'
#  See snmpd.conf(5) for more details
sysLocation    My Location with Spaces
sysContact     My Name with Spaces
                                                 # Application + End-to-End layers
sysServices    72


#
#  Process Monitoring
#
                               # At least one  'mountd' process
proc  mountd
                               # No more than 4 'ntalkd' processes - 0 is OK
proc  ntalkd    4
                               # At least one 'sendmail' process, but no more than 10
proc  sendmail 10 1

#  Walk the UCD-SNMP-MIB::prTable to see the resulting output
#  Note that this table will be empty if there are no "proc" entries in the snmpd.conf file


#
#  Disk Monitoring
#
                               # 10MBs required on root disk, 5% free on /var, 10% free on all other disks
disk       /     10000
disk       /var  5%
includeAllDisks  10%

#  Walk the UCD-SNMP-MIB::dskTable to see the resulting output
#  Note that this table will be empty if there are no "disk" entries in the snmpd.conf file


#
#  System Load
#
                               # Unacceptable 1-, 5-, and 15-minute load averages
load   12 10 5

#  Walk the UCD-SNMP-MIB::laTable to see the resulting output
#  Note that this table *will* be populated, even without a "load" entry in the snmpd.conf file



###############################################################################
#
#  ACTIVE MONITORING
#

                                    #   send SNMPv1  traps
 trapsink     localhost public
                                    #   send SNMPv2c traps
#trap2sink    localhost public
                                    #   send SNMPv2c INFORMs
#informsink   localhost public

#  Note that you typically only want *one* of these three lines
#  Uncommenting two (or all three) will result in multiple copies of each notification.


#
#  Event MIB - automatically generate alerts
#
                                   # Remember to activate the 'createUser' lines above
iquerySecName   internalUser       
rouser          internalUser
                                   # generate traps on UCD error conditions
defaultMonitors          yes
                                   # generate traps on linkUp/Down
linkUpDownNotifications  yes



###############################################################################
#
#  EXTENDING THE AGENT
#

#
#  Arbitrary extension commands
#
 extend    test1   /bin/echo  Hello, world!
 extend-sh test2   echo Hello, world! ; echo Hi there ; exit 35
#extend-sh test3   /bin/sh /tmp/shtest

#  Note that this last entry requires the script '/tmp/shtest' to be created first,
#    containing the same three shell commands, before the line is uncommented

#  Walk the NET-SNMP-EXTEND-MIB tables (nsExtendConfigTable, nsExtendOutput1Table
#     and nsExtendOutput2Table) to see the resulting output

#  Note that the "extend" directive supercedes the previous "exec" and "sh" directives
#  However, walking the UCD-SNMP-MIB::extTable should still returns the same output,
#     as well as the fuller results in the above tables.


#
#  "Pass-through" MIB extension command
#
#pass .1.3.6.1.4.1.8072.2.255  /bin/sh       PREFIX/local/passtest
#pass .1.3.6.1.4.1.8072.2.255  /usr/bin/perl PREFIX/local/passtest.pl

# Note that this requires one of the two 'passtest' scripts to be installed first,
#    before the appropriate line is uncommented.
# These scripts can be found in the 'local' directory of the source distribution,
#     and are not installed automatically.

#  Walk the NET-SNMP-PASS-MIB::netSnmpPassExamples subtree to see the resulting output


#
#  AgentX Sub-agents
#
                                           #  Run as an AgentX master agent
 master          agentx
                                           #  Listen for network connections (from localhost)
                                           #    rather than the default named socket /var/agentx/master
#agentXSocket    tcp:localhost:705

Discussing the IT landscape and impacts of the COVID-19 pandemic

You should check out the Twitter Handles of the Ambassadors soon.
I just had the greatest time discussing the impact on the IT landscape during the COVID-19 pandemic.

This Juniper Networks Ambassador Roundtable featured Michael Marcellin, CMO at Juniper, and from the Ambassadors Stefan Fouant, Chris Parker, Nick Ryce, Paul Clarke, Andrew Alston, Tom Dwyer and myself.
You will soon find it also on this blog πŸ™‚

vSRX 3.0 Template for EVE-NG

Here you find the vSRX 3.0 custom template for your EVE-NG.

Add this file (named vsrx30.yml) to your /opt/unetlab/html/templates/intel/ folder:


# Copyright (c) 2016, Andrea Dainese
# Copyright (c) 2016, Alain Degreffe
# Copyright (c) 2017, Alain Degreffe
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the UNetLab Ltd nor  the name of EVE-NG Ltd nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---
type: qemu
name: vSRX3-0
cpulimit: 1
icon: JuniperSRX.png
cpu: 2
ram: 4096
eth_name:
- fxp0/mgmt
eth_format: ge-0/0/{0}
ethernet: 6
qemu_nic: virtio-net-pci
console: telnet
qemu_arch: x86_64
qemu_options: -machine type=pc-1.0,accel=kvm -cpu qemu64,+ssse3,+sse4.1,+sse4.2,+x2apic,+aes,pclmulqdq  -serial
  mon:stdio -nographic   -nodefconfig -nodefaults -rtc base=utc

Don’t forget to include it in your custom_templates file at /opt/unetlab/html/includes/custom_templates.yml:

custom_templates:
- name: JATP
  listname: 'Juniper JATP Appliance (SkyATP on Premise)'
- name: PACKETFENCE
  listname: 'PacketFence OpenSource NAC'
- name: CSRX
  listname: 'Juniper cSRX'
- name: vsrx30
  listname: 'Juniper vSRX3.0'
- name: jspacelogcollector
  listname: 'JunOS Space Log Collector'

Compared to the vSRX-NG Template, which took the vSRX 3.0 6-7min to fully boot, this “new” template (which is basically a linux based template) takes roughly 2-3min to fully boot with 19.4 and 20.1 πŸ˜‰

Enjoy your unleashed vSRX3.0 πŸ™‚
Feel free to ask questions / suggestions in the comments here πŸ™‚

EVE-NG Update in IPv6 only environments

The newest eve-ng ( 2.0.6-42(+43+44)-PRO // 2.0.3-108-Community) introduces a lot of cool new features for making your daily work easier than ever, that I will cover in the next few days.

I had some issues while updating my eve-ng (because I run my eve-ng IPv6 only – and yes – v6 ONLY)

If you have v4 only or Dual-Stack, this “problem” is something, that you will not face.
All IPv6 only guys can keep on reading.

During the upgrade, the eve-ng-pro package (I’m sure community does the same) disabled IPv6 since having IPv6 enabled during the update process could break stuff – great for my eve-ng because this way my installation is safe, but bad for my connectivity because if you run IPv6 only like I do – you’ve guessed it – game over for remote access πŸ˜€

Here’s how I “rehabilitated” my eve-ng:
Luckily, I have ILO Access to my Server – else, due to COVID-19 and travel “restrictions” this would have been a whole other game…

I opened a Remote Console and logged into eve-ng after giving it some time for the update.
First was a reboot (you should always do this after upgrades).
When it was reachable again, I logged in and looked inside my Syslog file, how ipv6 was disabled.
I found out, that /opt/ovf/ovfstartup.sh disabled ipv6 completely (sysctl -w net.ipv6.conf.all.disable_ipv6=1).

Usually, the script reflects the settings in your /opt/unetlab/html/includes/config.yml (that you edit by setting stuff via web-interface). I’m sure, that this file was changed by the updater from:

#Disable ipv6 on EVE Host
grep -q 'ipv6.*0' /opt/unetlab/html/includes/config.yml 2>/dev/null && sysctl -w net.ipv6.conf.all.disable_ipv6=1
grep -q 'ipv6 ' /opt/unetlab/html/includes/config.yml 2>/dev/null || sysctl -w net.ipv6.conf.all.disable_ipv6=0

to the new “update settings”:

#Disable ipv6 on EVE Host
grep -q 'ipv6.*0' /opt/unetlab/html/includes/config.yml 2>/dev/null && sysctl -w net.ipv6.conf.all.disable_ipv6=1
grep -q 'ipv6 ' /opt/unetlab/html/includes/config.yml 2>/dev/null || sysctl -w net.ipv6.conf.all.disable_ipv6=1

so that regardless of your settings in the web-interface it would make sure, that ipv6 is disabled.

So far so good.

I changed the second line back (grep -q ‘ipv6 ‘ /opt/unetlab/html/includes/config.yml 2>/dev/null || sysctl -w net.ipv6.conf.all.disable_ipv6=0) and rebooted my eve-ng – TADAA – pnet0 has it’s IPv6 address back πŸ™‚

I also modified the script a bit because in IPv6 only networks it would always show you “no ip address on pnet0” on the console instead of your usual “login to http://…..” – after modifying it, it now also shows IPv6 on the console – but the next update will probably break that since I manually edited the file (you shouldn’t do that until you know EXACTLY what you are doing – I repeat – this is NO NO stuff πŸ˜›

Here’s what I did:

Change:

IP="$(ifconfig ${INTERFACE} 2> /dev/null | grep 'inet addr' | cut -d: -f2 | cut -d' ' -f1 | grep -E "^[0-9]+.[0-9]+.[0-9]+.[0-9]+$")"

on interface pnet0 to this:

IP="$(ip -o -6 addr show pnet0 | sed -e 's/^.*inet6 \([^ ]\+\).*/\1/' | grep -v ^fe80)"

It still shows /64 behind the URL because I don’t really know how to use awk but hey – it’s a start πŸ˜‰
The endgame would be to set the URL to https://[2001…..]/ since IPv6 needs braces [ ] in the URL – but that’s just cosmetic.

In the next few days, I will try to upload more Articles and Videos but due to COVID-19, my workload has increased by roughly 900%… Stay Safe guys!