Friday 20 March 2015

Adding PSTN to LAB

Setting up the lab has been a good exercise, but not being able to interact with the PSTN was disappointing. Fortunately I mentioned this to a colleague and within minutes I had in my hand a Linksys PSA 3102 VOIP Gateway. This is now in my lab and working inbound and outbound from both Asterisk and Lync 2013, so I thought I would document the process.


The PSA itself has 4 ports, Line, Phone, Ethernet, Internet. Software Version 5.1.7(GW), Hardware 1.1.5.


The server running my lab only has two NIC's, one external and one internal, so temporarily to set this up I had to disconnect the external NIC so that I could connect it to the PSA's Ethernet port. I also unplugged my PSTN line from my BIX wall and connected the PSA directly to it via the LINE port.


A few details around getting the PSA up and running. It was a used device with an irretrievable password, so I had to reset to factory defaults. There is no button for this. You need to connect a regular house phone to the PHONE port. When you pickup the phone you go into a prompt. Cisco has the quick start guide on their page for the remaining steps.


PSA Configuration

Once the device was reset, I was able to get onto its Web GUI via 192.168.0.1 and make some configuration changes, many of which I was able to figure out thanks to this excellent post. I set the IP to match my internal network and set the following.

[[Router]]
[Lan Setup]
Networking Service = Bridge
Enable DHCP Server = No

[[Voice]]
[Provisioning]
Provision Enable = No
[Line 1]
Line Enable = No (because I do not have a phone attached to the PHONE port)
[PSTN Line]
Line Enable = Yes
SIP Transport = TCP
SIP Port = 5061
Auth INVITE = No
Proxy = IP of Asterisk Server
Register = Yes
<Subscriber Information>
Display Name = Anything
User ID = 1-pstn (this matches the trunk in Asterisk)
Password = Matches the secret password set on the trunk in Asterisk
Use Auth ID = no
Dial Plan 2 = (S0<:xxxxxxxxxx>) <-- This needs to be your PSTN line # for inbound calls to work
VoIP-To-PSTN Gateway Enable = Yes
PSTN-To-VoIP Gateway Enable = Yes
PSTN Caller Default DP = 2


Asterisk Configuration

Now for the Asterisk configuration, also via WEB GUI.

1. Create a trunk to the SPA

For the Outgoing Settings PEER Details window, enter the following:
allow=ulaw
canreinvite=no
context=from-trunk
dtmfmode=rfc2833
host=dynamic
incominglimit=1
nat=never
port=5061
qualify=yes
secret=Matches the secret password set on the PSA
type=friend
username=1-pstn (this matches the PSA config)

2. Create an Outbound Route to the SPA so that any call coming to Asterisk that matches the dial pattern below will get sent to the SPA.

Dial Pattern = NXXNXXXXXX
Trunk Sequence for matched route = 1-pstn

3. Create an Inbound Route so that you can receive calls from the PSTN that come from the SPA
Description = SPA3102
DID Number = xxxxxxxxxx (Make sure this matches the DID you put into Dial Plan 2 on the SPA)
Set Destination = Wherever you want it to go. I had a 3002 Extension configured in Asterisk and initially sent it there and then I also set up a user within Lync with the DID number and sent it to the Lync trunk which I will cover the setup of in the next part.

To be continued for Lync 2013 configuration...

Thursday 29 January 2015

My Lync 2013 Lab

As of today my lab consists of the following:
1 x Dell 690 Workstation (2 x Xeon 3.2Ghz Dual Core CPU)
16GB RAM  (2 x 8 PC2 5300)
4 x SATA Drives ~250GB each
2 x NIC (1 = LAN, 1 = WAN)
OS = ESXi 5.5

This server is currently hosting 20 VM's although generally ~14 can be powered on at a time before resources become an issue - mostly RAM and then everything becomes very slow. 

I will focus this post on just the Lync 2013 environment for now, excluding the Asterisk PBX integration and Exchange 2013 integration.

The domain is mtest.local. I also have subdomain, sub.mtest.local which was used to simulate a client site however generally I try to put everything into the root domain.

The network configuration
Both NIC's are plugged into my ISP router. One NIC is on a vSwitch labelled LAN, the other on a vSwitch labelled WAN.

The DMZ has two guests on it:
PFSense (Firewall, Reverse Proxy)
WAN IP 192.168.1.199
LAN IP 192.168.0.205

LyncEdge.mtest.local
WAN IP 192.168.1.99
LAN IP 192.168.0.99

The ISP Router DMZ configuration is pointed to 192.168.1.199. PFSense is then able to manage all external connections as per the firewall configuration.

The Lync Environment (all 1 CPU, 4GB unless otherwise specified)

PROD
DCRoot.mtest.local (2008 R2 Domain Controller, 1CPU, 1GB)
PFSense (FreeBSD based Firewall/Router/Reverse Proxy, 1 CPU, 1GB)
LyncEdge.mtest.local (Lync Edge Server in DMZ)
LyncFE.mtest.local (PROD FE Server)
LyncFE-a.mtest.local (PROD FE Server)
LyncFE-b.mtest.local (PROD FE Server)
SQL.mtest.local (PROD SQL Server, mirrored with SQL-A)
SQL-a.mtest.local (PROD SQL Server, mirrored with SQL)

DR
LyncFE2.mtest.local
SQL2.mtest.local

*Note to self: Plan a naming scheme next time :)


External DNS
Access/SIP/LyncDiscover/LyncWeb/LyncWebCoq.domain.com all point to my ISP IP.

There is also a _sip._tls.domain.com SRV record pointing to access.domain.com on port 4433.



PFSense Firewall Config
Rules:
TCP * * WAN Address 5555 * none <-- Goes to lyncwebcoq.domain.com (DR Lync Pool)
TCP * * WAN Address 4333 * none <-- Goes to lyncweb.domain.com (PROD Lync Pool)
TCP * * 192.168.1.99 5061 * none (NAT Rule, refer below)
TCP * * 192.168.1.99 4433 * none (NAT Rule, refer below)

UDP * * 192.168.1.99 3478 * none (NAT Rule, refer below)
TCP/UDP * * 192.168.1.99 50000-59999 * none (NAT Rule, refer below)
TCP * * 192.168.1.99 4444 * none (NAT Rule, refer below)


NAT
WAN TCP * * WAN address 5061 192.168.1.99 5061 <-- Goes to Edge Server (Only 1 for both pools atm)
WAN TCP/UDP * * WAN address 50000-59999 192.168.1.99 50000-59999 (Goes to Edge for RTP Ports)
WAN UDP * * WAN address 3478 192.168.1.99 3478 (STUN Protocol to Edge)
WAN TCP * * WAN address 4433 192.168.1.99 4433 (A/V port on Edge)
WAN TCP * * WAN address 4444 192.168.1.99 4444 (Web Conf Port)

Reverse Proxy
The Reverse Proxy is within PFSense and is the Squid3 package.

It is configured to for the WAN interface on IP 192.168.1.199 with external FQDN domain.com. Everything is default other than what I've specified. The Reverse Proxy port is either 4333 or 5555 depending on whether I want the requests going to PROD or DR.

The Reverse SSL Certificate also must be configured via PFSense Cert Manager. Under Certificates, Add a new certificate and input the external facing lyncweb.domain.com certificate. This cert should have your external facing Lync Web and Simple URLs (lyncweb, meet, dialin, lyncdiscover). To add the certificate it must be extracted from PFX format with the private key. A couple of notes here:

1. When requesting this certificate via Lync Deployment Wizard, Mark as Exportable MUST be checked otherwise you cannot export the private key. 

2. The PFX can be extracted into a PEM and KEY file with OpenSSL (download the Windows Binary, extract to C:\openssl). Copy the PFX file there and run the following:
    openssl pkcs12 -in certname.pfx -nocerts -out key.pem -nodes
    openssl pkcs12 -in certname.pfx -nokeys -out cert.pem
You can then copy these contents into the certificate manager accordingly and the certificate will be available in the Reverse Proxy configuration General tab. Also note that you will need to have two certificates in here, one for the PROD environment and one for DR so that when you switch between the two both certificates are available.

The Web Servers tab needs to have an entry for LyncWeb pointing to the IP of the FE (again make sure to change this when switching PROD/TR). The Peer port is 4443, this is the port the FE is listening on by default for external Web connections. 

The Mappings tab needs to have a mapping to LyncWeb as well. The URIs can be added here for both PROD and DR like this:
^https://lyncweb.domain.ca:4333/.*
^https://lyncdiscover.domain.ca:4333/.*
^https://lyncwebDR.domain.ca:5555/.*
^https://lyncdiscover.domain.ca:5555/.*

Note that Lyncdiscover has to remain the same URL however it can be in here twice because of the different ports being used. I had to do this because my ISP blocks 80/443 so standard ports cannot be used.

Few issues I've run into so far when configuring this:
1. Do not use spaces in names in PFSense. Anywhere. It wouldn't start anymore because I put a space in a peer name. This really goes for Lync too, spaces are just troublesome and should be avoided along with any other non alphanumeric characters.

2. LyncDiscover can be fickle. For some reason one of my FE's although running fine did not have the "Lync Web App" started - I'm not sure how to start this manually at the moment but suspect Get-CSWindowsService may have the answer. 
Anyway, when I would access lyncdiscoverinternal.mtest.local in a browser (DNS entry being a cname to lyncpool.mtest.local) it would point me to LyncFE-A and say page cannot load. After accessing the server via https://lyncpool.mtest.local suddenly in event viewer the Lync Web App started and then accessing LyncDiscoverInternal also works. This is an issue because the Lync 2013 clients are relying on this and when it wasn't working, the EndpointConfigurationCache was blank and the client would not connect. As soon as the "Lync Web App Started" entry appeared, the client was properly able to discover the server and populate that file.

3. External Lync Mobile Client. I was testing using my Android and for some reason it refused to connect although everything checked out. It turns out that on my network, 4G seems to have an issue connecting whereas LTE works fine. I stumbled upon this by chance when I went for a drive and suddenly the network switched and my Lync client signed in. Odd. 
Also with this client if you need to setup manual configuration for any reason, the path is this:
https://lyncweb.domain.ca:4333/AutoDiscover/autodiscoverservice.svc/Root

And if for some reason it still can't connect, use the browser and make sure that URL loads a XML file with the URL's the client will use. If it doesn't, you have an issue likely at the Reverse Proxy config.

 4. Edge <-> Internal calls were failing to connect. I used the CLS Logging Tool and found in the logs that connections from the FE's to Edge on 5062 were failing. This is the Edge A/V Auth port. I ran Netstat -a and could see the port was not listening. I then restarted the service and ran Netstat -a again and could see 5062 was now established to the FE's. The calling issue was also resolved.

Packet Capture
I've also taken a few packet captures to see the ports being utilized during an audio call from Edge to Internal.

Mobile Client is performing all activity via the Lyncweb 4333 port.



Lync 2013 client via Edge, utilized ports 3478 (STUN), 5061 (SIP), 4433 (AV Edge)

Thursday 13 November 2014

Exchange 2010 SP1 - Deleting Email From All Mailboxes

1. Create an AD Universal Group, "Import Export Admins" for example.
2. Add the account that will run the shell command to this group.
3. New-ManagementRoleAssignment -Name "Import Export Admins" -SecurityGroup Import Export Admins" -Role "Mailbox Import Export"
4. Get-mailbox -server "SERVERNAME" | Search-Mailbox -SearchQuery 'Subject: "INSERT SUBJECT HERE"',"Received:11/13/2014" -targetmailbox "RecoveryMailbox" -targetfolder "SearchResults" -logonly -loglevel full

TargetMailbox is any mailbox that you want the log results to go into.
TargetFolder is the folder that will be created in the mailbox with the results.

The above command will only output the log to the mailbox with an attached CSV file. Nothing is deleted yet. Review the file and proceed with the next step if all results are acceptable.

5. Get-mailbox -server "SERVERNAME" | Search-Mailbox -SearchQuery 'Subject: "INSERT SUBJECT HERE"',"Received:11/13/2014" -targetmailbox "RecoveryMailbox" -targetfolder "SearchResults" -loglevel full -DeleteContent

The above command will create a "User, Name - Date" subfolder under the TargetFolder for every mailbox it accessed to delete the file. It will also leave a copy of the deleted message in these folders for review. Make sure if doing this that the mailbox has sufficient size. If the size of the mailbox is exceeded, the command will fail with an error about exceeding a condition.

If having a copy is not necessary, the following command can be run instead:

Get-mailbox -server "SERVERNAME" | Search-Mailbox -SearchQuery 'Subject: "INSERT SUBJECT HERE"',"Received:11/13/2014" -DeleteContent

Thursday 16 August 2012

Useful little script for querying uptime of list of servers

Combine with Microsoft's uptime.exe (http://support.microsoft.com/kb/232243)
for /f "tokens=* delims= " %%a in (server.txt) do (
uptime.exe %%a >> results.txt
)

Friday 29 June 2012

Convert KMS Host to Client

Converting KMS Host to Client

Windows 7 & Server 2008 R2 volume license copies both come with KMS Client keys installed by default. These are also obtainable from here: http://technet.microsoft.com/en-us/library/ff793421.aspx

If a server is accidentally activated with the KMS host key, it can be changed back via:
slmgr.vbs -ipk xxxx-xxxx-xxxx-xxxx-xxxx (replace x's with the OS specific KMS key from the above site)

To check the status of the existing key on the server, run: slmgr.vbs -dlv

The "Description" should list VOLUME_KMSCLIENT channel. If the server was activated with a KMS host key, it will show VOLUME_KMS_B channel and below will also state "Key Management Service is enabled on this machine"

Tuesday 22 November 2011

Server 2008 - Remotely adding/removing users from Groups

runas /user:domain\username "psexec \\server net localgroup test domain\username {/add or /delete}"

Monday 14 November 2011

Remotely installing SNMP on Server 2008

1. On one server, install SNMP 2008 (C:\ocsetup SNMP), configure the service and export HKLM\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ to C:\snmp.reg


2. Create a batch file that will a). import the key exported from step 1. b). delete the 1 value which needs to be removed to allow 'Any host' to connect to the SNMP service.
reg import C:\snmp\snmp.reg
reg delete HKLM\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\PermittedManagers /v 1 /f


3. Copy these files to all of the servers via this script (make sure to create the C:\computers.txt and populate):
Const ForReading = 1
Const OverwriteExisting = TRUE
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\computers.txt")
Do Until objFile.AtEndOfStream
    strComputer = objFile.ReadLine
    strRemoteFile = "\\" & strComputer & "\C$\snmp.reg"
    objFSO.CopyFile "C:\snmp\snmp.reg", strRemoteFile, OverwriteExisting
Loop


4. Use psexec to execute the snmp.bat on each server via:
C:\runas /user:domain\username "psexec \\server\ C:\snmp.bat"


5. Use snmpwalk from this page and run
snmpwalk -v 1 -c community-here 127.0.0.1

6. Remove all of the files using:
Const ForReading = 1
Const OverwriteExisting = TRUE

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\computers.txt")

Do Until objFile.AtEndOfStream
    strComputer = objFile.ReadLine
    strRemoteFile = "\\" & strComputer & "\C$\snmp.reg"
    objFSO.DeleteFile strRemoteFile
Loop



Steps 4 & 6 can be improved by getting the @file command with psexec, but since it's paired with runas it might be tricky to get that to work.