Friday, November 16, 2018

Fortigate SSL VPN with LDAP User Authentication

The documentation was pretty inaccurate/unclear on a lot of this, so there was a bit of trial and error. This assumes you're already familiar with setting up SSL VPN and already have it working with local user accounts. Here's how you do it:


Pre-requisites

  • You need your SSL VPN portal and settings configured already
  • You should also have already created your SSL VPN policy (allowing from the SSL VPN interface to your LAN)
  • The above requires you to add a user or group already, you can re-use that group for the items below if desired

Set up LDAP Server

I'm using Active Directory, but you can use any LDAP based directory service. The example below assumes your AD domain is domain.local.

  1. Navigate to User & Device > LDAP Server
  2. Add a new server and enter the settings:
    • Name: this is the friendly name, i usually just put the hostname in
    • Server IP: obvious
    • Server Port: leave this default unless you know what you're doing
    • Common Name Identifier: This defaults to CN, which means Common Name. This is dumb. Your users are not going to log in as "Bob Smith", they're going to log in as bsmith or bsmith@domain.com. Set this to userprincipalname if you want them to use their UPN (username@domain.com) or maybe samaccountname if you want them to just use their username.
    • Distinguished Name: You can't use the Browse button until you fill out the rest of this page, but this can just be DC=domain,DC=local. Note: if you choose to scope this further than the domain as listed, your group (in the next section) must be in scope.
    • Bind Type: Regular
    • Username/Password: You can start off with a domain admin for testing, but ultimately you should create an unprivileged service account to use here
    • Secure Connection/Protocol: I used secure and selected LDAPS. If you don't have LDAPS then don't use it.
    • At this point you should be able to Test Connectivity and get a success.

Set up your group

  1. In Active Directory, create a group and add users to it. I called mine SSL VPN Users
  2. In the Fortigate, navigate to User & Device > User Groups
  3. Click on Create New
  4. Name the group the same as you created in AD (this isn't important, just a friendly name)
  5. Select Firewall as the type
  6. Under the Remote Groups section, click Add, select your LDAP server, and then search/select your group.
  7. Important: You have to right click on it and select Add Selected. After that, hit OK, not before.
  8. Hit OK again to save the group
  9. Configure your SSL VPN firewall policy to use this group for authentication

Testing

At this point you should be done, because you already set up your SSL VPN, right? You should be able to log in as the user now, you can go to Log & Report > VPN Events to see what the error is if you're not able to log in. You can also use the command diag test authserver ldap "YOUR LDAP SERVER NAME" youraccount@domain.com yourpassword to do a direct test.

Wednesday, October 31, 2018

Apple Open Directory - Options Greyed Out after IP Change

I recently had to move a few Apple servers from one site to another for a client, and after the move the Open Directory was half-working (opens, lets you view users, but can't add/remove/edit). There were a few no-brainer fixes that i had to do initially, but at the end of the day the final fix was pretty much a bandaid.

Overall obvious steps:

  1. Make sure your hosts file (/etc/hosts) is referencing the right IPs, in case anything changed.
  2. Make sure the system is set to the right IP(s) for DNS.
  3. Make sure the DNS Server records are updated to the new/correct IPs for both the forward and reverse zones.

The bandaid fix for me

In my case, when authenticating within the Workgroup Manager, it would lag and then eventually log in. Nothing in the logs about what was wrong, but the New User button was greyed out, as well as all of the fields on the actual accounts. For whatever reason i could reset passwords, not sure why. The ultimate fix was to add an additional network interface to the server, and set the IP address to the old IP of the server. Yep.

Troubleshooting Steps

  • First i fired up tcpdump and did a filter of "port 53" to see if any DNS requests were going out or coming back in incorrectly. Didn't find anything there.
  • Next i did tcpdump "host 10.x.x.x" (with the old IP of the server) on a hunch, to see if it was trying to send any traffic there. And yep, it was, on port 389 (LDAP).
  • Knowing that, i did a grep for the IP in /etc and a few other places but couldn't find it, assuming it's in a binary DB somewhere or something. So the only solution is to make the traffic actually connect.
  • In Networking, i added a new interface under the existing Ethernet, gave it the same IP of the server before the move, but with subnet mask 255.255.255.255. This allows the IP to respond without interfering with any other IPs on the subnet.
  • After making that change, the directory connected and started working instantly.

Thursday, August 30, 2018

Migrating to Office 365 from BAE Systems / Silversky Hosted Exchange

This was a fun one... not an easy process to figure out so hopefully this helps someone. To migrate away from the BAE Systems aka Silversky Hosted Exchange platform, you need to get a few things:
  1. Your Office 365 organization should already be set up and ready to go (obviously)
  2. An admin account in Hosted Exchange that has Full Access to the mailboxes you wish to migrate, and is a licensed user (has an Exchange package)
  3. Either an Outlook installation you can use, or the testconnectivity.microsoft.com website will also do.
  4. Access to the BAE Systems Exchange Provisioning Console (it's a java app)

Office 365 Setup

At this point you should have your organization created, domain added, and at least one licensed user (admin account is ok). That part of the setup is far out of scope for this guide.

Getting Admin Access

If you have just a few mailboxes, then you can just do this yourself. I highly recommend you test this with one or two mailboxes first, as i have had the built-in cusrpt@ account not work correctly.

For each user:

  1. Open the user account in the provisioning console
  2. Go to Packages, and edit the Exchange package
  3. Launch the Mailbox Rights Management window
  4. Add your admin account and grant it Full Access
  5. Save all the way out, rinse and repeat

If you have a ton of mailboxes, then you may need to call support. You can launch multiple instances of the provisioning console to pipeline the requests, but i just did 500 users, so that wasn't happening. In that case, you can call support and get them to run a Powershell command to grant you access. It may take a little work to get them to escalate it, and they also may want to charge you for it. I'm not going to go over the details of the command here, you can google that one.

Starting the Migration Batch

  1. Open the Exchange admin center, and head over to Recipients/Migration
  2. Create a new Migration batch, "Migrate to Exchange Online"
  3. Set the batch type to Cutover
  4. Enter the account credentials that you set up in the previous section (the one with access to all the mailboxes)
  5. It will probably give you an error at this point, that's why this guide exists. You now need to enter the Exchange server and RPC proxy server. Here we go...
    The easy part first: set the RPC proxy to exchange.postoffice.net. Now the hard part. Use either the testconnectivity.microsoft.com website, or (for the security conscious) your Outlook's Autodiscover feature. To use the former, just go to the website and enter the info, doing an Autodiscover test. To use the latter, ctrl+click on your Outlook icon, go to Test E-mail Autoconfiguration, enter the credentials and un-check the Guessmart options.

    At this point, regardless of the option, you will end up with the Autodiscover XML output. In here, you will see a section that says:

    <Protocol>
      <Type>EXCH</Type>
      <Server>2bd60169-a9ac-4f15-bdd4-dea1a11129a7@yourdomain.com</Server>
    

    You need to copy/paste the contents of the Server tag (the part that looks like an email address, including the @yourdomain.com). This is what you use for the Exchange server field.
  6. Once you've done that, you do need to use the advanced/more option and set Authentication to Basic and Mailbox Permission to Full Access and hit Next
  7. Name your batch, select the notification email (aren't you glad i told you to have at least one licensed user?), and you can start.
At this point, you're migrating. You can monitor the batch status from the console like you normally would. If doing a large number of mailboxes, use Powershell.

Monday, July 2, 2018

Fortigate - Policy Routing to VPN Tunnels

I have found that FortiOS v6+ has slightly different/broken functionality when handling policy routes across VPN tunnels (phase1/2-interface). In v5 you could create a policy route pointing to the tunnel interface and leave the gateway address set to 0.0.0.0, and everything worked fine. In v6 however, it appears leaving it as 0.0.0.0 is Fortinet code for please don't use me, i'm stupid.


The fix is pretty simple, assign an IP on both sides on the tunnel interface (just a /30 is fine, i.e. 10.255.255.1/30 and 10.255.255.2/30). Then in the policy routes, reference that IP as the gateway, and it should start working.


Sample Config:

(Note that in this case, the tunnel was to route all internet bound traffic across the VPN, so yours may look different)

Firewall 1

config system interface
    edit "Corp"
        set vdom "root"
        set ip 10.153.153.2 255.255.255.255
        set type tunnel
        set remote-ip 10.3.153.1 255.255.255.252
        set interface "wan1"
    next
end

config router policy
    edit 1
        set input-device "internal"
        set src "10.2.53.0/255.255.255.0"
        set dst "0.0.0.0/0.0.0.0"
        set gateway 10.153.153.1
        set output-device "Corp"
    next
end

Firewall 2

config system interface
    edit "Remote"
        set vdom "root"
        set ip 10.153.153.1 255.255.255.255
        set type tunnel
        set remote-ip 10.3.153.2 255.255.255.252
        set interface "wan1"
    next
end

config router policy
    edit 1
        set input-device "internal"
        set src "0.0.0.0/0.0.0.0"
        set dst "10.2.53.0/255.255.255.0"
        set gateway 10.153.153.2
        set output-device "Remote"
    next
end

Monday, May 7, 2018

Automatically Rotating Group Policy Logon Messages

This is a pretty common task for various types of compliance, where you use the logon message via GPO to display security notices or other company facts. But you can't just have a stale message, it needs to be rotated to keep it fresh. I got tired of doing mine by hand, so i wrote a script to do it. Unfortunately the PowerShell Group Policy module has pretty poor documentation, and i'm not even confident it's capable of doing this. That said, some group policies use files in SYSVOL, while others store their data in AD. In this case, it's in a .inf file, so here is the powershell script:

$basepath="\\yourdomain.local\sysvol\yourdomain.local\policies\{CF267D2E-F5BE-46D9-85B3-58125FEFB1CF}\machine\microsoft\windows nt\secedit"
$tmpfile="$basepath\tmp.inf"
$tplfile="$basepath\GptTmpl.inf"
$bakfile="$basepath\GptTmpl_bak.txt"
$notices=@(
    "Your first notice.",
    "Your second notice.",
    "Etc."
)

$phrase=$notices[(get-random -Maximum ([array]$notices).count)]
$phrase=$phrase -replace ",","`",`""  #the .inf wraps commas in quotes when it's part of the string

new-item -path $tmpfile -ItemType file -Force | out-null
foreach ( $line in get-content $tplfile ) {
    if ( $line -match "LegalNoticeText" ) {
        "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeText=7,$phrase" | out-file -filepath $tmpfile -append
    } else {
        $line | out-file -filepath $tmpfile -append
    }
}
move-item $tplfile $bakfile -Force
move-item $tmpfile $tplfile

Just get the GUID of the GPO you're using from GPMC and replace it in the $basepath, and you're set. Run that as an account with permission to that path and it will automatically rotate it.

Wednesday, April 25, 2018

Exchange 2010 Installation Fails with Error "Provisioning layer initialization failed"

For a customer with an older environment, needed to re-build a DAG member and ran into this issue. Upon installation of the management tools, even with a fresh SP3 download, the install would error out. The guts of the error messages were this:


[04/24/2018 22:21:56.0372] [2] [ERROR] Provisioning layer initialization failed: '"Scripting Agent initialization failed: "File is not found: 'C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'.""'
[04/24/2018 22:21:56.0372] [2] [ERROR] "Scripting Agent initialization failed: "File is not found: 'C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'.""
[04/24/2018 22:21:56.0372] [2] [ERROR] "File is not found: 'C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'."
[04/24/2018 22:21:56.0388] [2] [ERROR] Provisioning layer initialization failed: '"Scripting Agent initialization failed: "File is not found: 'C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'.""'
[04/24/2018 22:21:56.0388] [2] [ERROR] "Scripting Agent initialization failed: "File is not found: 'C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'.""
[04/24/2018 22:21:56.0388] [2] [ERROR] "File is not found: 'C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'."
Turns out, this is related to the PowerShell cmdlet Extension called Scripting Agent, which is enabled by default. Many posts online say you can just go to the path listed above and rename the .sample file to fix it, but that doesn't actually fix the management tools. In actuality, you need to disable the agent, run the install, then (if desired) re-enable the agent.


  1. Open a the EMS (Exchange Management Shell) on another exchange server in the org and run:
    Disable-CmdletExtensionAgent "Scripting Agent"
  2. Fully install Exchange
  3. Copy C:\Program Files\Microsoft\Exchange Server\V14\bin\CmdletExtensionAgents\ScriptingAgentConfig.xml from another exchange server to the same path on the new server
  4. Re-enable the agent:
    Enable-CmdletExtensionAgent "Scripting Agent"
I suppose not much Microsoft could do to work around this without releasing a new service pack, but still frustrating.

Friday, December 8, 2017

ConnectWise Manage Report Writer - Repeaters and Subtotals

If you're reading this you're probably aware that the support/documentation provided by ConnectWise for more difficult tasks in Report Writer is a bit... lacking. I ran into a few issues on Saturday and while i figured them all out the same day, i did a CW chat and submitted a ticket and have yet to hear back (4 full business days later). Basically, if you want to use Repeaters and/or Subtotals, there are very specific constraints that you need to keep in mind. This post is not for someone just getting into report writer, you need to already know how to build queries, use joins, and more.

Repeaters

These are a great solution to not having to use a sub-report. That said, they're not very intuitive and are in fact pretty basic in nature. The gist of it is that once you start the repeater, the first column you reference and all subsequent ones (unless you hit a nested a repeater) are repeated until the initial column changes. The documentation flip flops between using [repeater], <!--[repeater]-->, and <repeater>. The latter is never correct. The first two can be used interchangeably, but if you're wrapping this around HTML content then the middle option is the correct one.

As an example, say you are making a report that lists a client's agreements with their additions. The data in table form may look like this:

Agreement NameAnniversaryAddition NameAddition QtyAddition PriceExtended Price
Managed Services1/1/2019Antivirus30$5.00$150.00
Managed Services1/1/2019Agent30$1.00$30.00
Managed Services1/1/2019Spam Filtering35$3.00$105.00
Telecom Support2/1/2020Handset Fee20$10.00$200.00
Telecom Support2/1/2020PBX Maintenance1$100.00$100.00

As you can see, the agreement name is duplicated for each time you have an addition on it, because this is how SQL works. So in Report Writer, on the Fields tab, you would click Design Form and then (if you're sane) edit the HTML directly. The code to put this together would look something like this:


[Company_Name]
<!--[repeater]-->
  <h3>[Agr_Name] - [Agr_Anniversary]</h3>
  <table>
    <tr><th>Item</th><th>Quantity</th><th>Cost</th><th>Ext Cost</th></tr>
    <!--[repeater]-->
      <tr>
        <td>[Line_Desc]</td>
        <td>[Qty]</td>
        <td>[Cost]</td>
        <td>[Ext]</td>
      </tr>
    <!--[/repeater]-->
  </table>
 <hr />
<!--[/repeater]-->

Note that there are nested repeaters. The first level is for the Agreement Name and Amount, the second level is for the items associated with each one. The resulting output looks something like this:


Company Name


Managed Services - 1/1/2019

ItemQuantityCostExt Cost
Antivirus30$5.00$150.00
Agent30$1.00$30.00
Spam Filtering35$3.00$105.00

Telecom - 2/1/2020

ItemQuantityCostExt Cost
Handset Fee20$10.00$200.00
PBX Maintenance1$100.00$100.00


Subtotals

Now let's say that you want to add up all of the addition amounts on the agreement and show that total. Since you still want the itemized list, you need to use the Subtotal Decorator. The CW Manage documentation flip flops on whether this is @Subtotal or #Subtotal, don't ask me why. The correct usage is @Subtotal. There are however a few constraints to consider:

  • Subtotal only makes sense in a repeater. If your data looks how you want it and you're not using a repeater, then this should be done in the query, not in the report designer.
  • You must check the VG (visual group) box on every column not part of the repeater that will be subtotaled. This will force them to be sorted as well, but that's not a big deal.
  • You must check the Add Subtotals box at the bottom of the Fields tab.
  • CW will tell you that you can only use Subtotal on one field. This is incorrect, you can subtotal as many fields in a repeater group as you want.
  • CW neglects to tell you that the column you are subtotaling cannot have spaces OR underscores in it.

Using the repeater example above, here is how you would add a subtotal of the overall ext costs of the additions:


[Company_Name]
<!--[repeater]-->
  <h3>[Agr_Name]</h3>
  <table>
    <tr><th>Item</th><th>Quantity</th><th>Cost</th><th>Ext Cost</th></tr>
    <!--[repeater]-->
      <tr>
        <td>[Line_Desc]</td>
        <td>[Qty]</td>
        <td>[Cost]</td>
        <td>[Ext]</td>
      </tr>
    <!--[/repeater]-->
    <tr><td colspan="3">Total:</td><td>[Ext@Subtotal]</td></tr>
  </table>
  <hr />
<!--[/repeater]-->

It's nice to note, the Subtotal can go above or below the repeater group. If you want to subtotal more than one column, just add that column with the @Subtotal decorator wherever you need.